TJOI2018 简要题解
数学计算
用线段树记录之前乘过的每一个数,作除法时把原本的乘数改成111即可。
代码:
#include<bits/stdc++.h>
#define lc (p<<1)
#define rc (p<<1|1)
#define mid (T[p].l+T[p].r>>1)
#define N 100005
using namespace std;
int t,n;
long long mod;
inline long long read(){
long long ans=0;
char ch=getchar();
while(!isdigit(ch))ch=getchar();
while(isdigit(ch))ans=(ans<<3)+(ans<<1)+ch-'0',ch=getchar();
return ans;
}
struct Node{int l,r;long long mul;}T[N<<2];
inline void pushup(int p){T[p].mul=T[lc].mul*T[rc].mul%mod;}
inline void build(int p,int l,int r){
T[p].l=l,T[p].r=r,T[p].mul=1;
if(l==r)return;
build(lc,l,mid);
build(rc,mid+1,r);
}
inline void update(int p,int k,int v){
if(T[p].l==T[p].r){
T[p].mul=v;
return;
}
if(k<=mid)update(lc,k,v);
else update(rc,k,v);
pushup(p);
}
int main(){
t=read();
while(t--){
n=read(),mod=read();
build(1,1,n);
for(int i=1;i<=n;++i){
int op=read();
if(op==1){long long v=read();update(1,i,v);}
else{int pos=read();update(1,pos,1);}
printf("%lld\n",T[1].mul);
}
}
return 0;
}
智力竞赛
这是一道语文阅读题
二分答案之后上最小链覆盖即可。
#include<bits/stdc++.h>
#define ri register int
using namespace std;
inline int read(){
int ans=0;
char ch=getchar();
while(!isdigit(ch))ch=getchar();
while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
return ans;
}
const int N=505;
bool trans[N][N],tmp[N][N],e[N][N],vis[N];
int mp[N],lim,n,m,matching[N];
struct Node{
int id,w;
friend inline bool operator<(const Node&a,const Node&b){return a.w<b.w;}
}a[N];
inline bool find(int x,int Lim){
for(ri i=1;i<=Lim;++i){
if(!trans[x][i]||vis[i])continue;
vis[i]=1;
if(!matching[i]||find(matching[i],Lim))return matching[i]=x,1;
}
return 0;
}
inline int match(int Lim){
int ret=0;
memset(matching,0,sizeof(matching));
for(ri i=1;i<=Lim;++i){
memset(vis,0,sizeof(vis));
if(find(i,Lim))++ret;
}
return ret;
}
inline bool check(int Lim){
memset(trans,0,sizeof(trans));
for(ri i=1;i<=Lim;++i)for(ri j=1;j<=Lim;++j)trans[i][j]=e[i][j];
for(ri k=1;k<=Lim;++k)for(ri i=1;i<=Lim;++i)if(trans[i][k])
for(ri j=1;j<=Lim;++j)if(trans[k][j])trans[i][j]=1;
return Lim-match(Lim)<=lim;
}
int main(){
lim=read()+1,n=read();
for(ri i=1;i<=n;++i){
a[i]=(Node){i,read()};
for(ri tt=read();tt;--tt)tmp[i][read()]=1;
}
sort(a+1,a+n+1);
for(ri i=1;i<=n;++i)mp[a[i].id]=i;
for(ri i=1;i<=n;++i)for(ri j=1;j<=n;++j)e[mp[i]][mp[j]]=tmp[i][j];
int l=1,r=n,ans=1;
while(l<=r){
int mid=l+r>>1;
if(check(mid))l=mid+1,ans=mid;
else r=mid-1;
}
if(r^n)cout<<a[ans+1].w;
else puts("AK");
return 0;
}
party
好题。
考虑lcslcslcs的性质。
fi,j=max{fi−1,j,fi,j−1,fi−1,j−1+[si==tj]}f_{i,j}=max\{f_{i-1,j},f_{i,j-1},f_{i-1,j-1}+[s_i==t_j]\}fi,j=max{fi−1,j,fi,j−1,fi−1,j−1+[si==tj]}
于是fi,j−fi−1,j=0/1f_{i,j}-f_{i-1,j}=0/1fi,j−fi−1,j=0/1,我们把这个东西拿来状压,然后转移即可。
代码:
#include<bits/stdc++.h>
#define ri register int
using namespace std;
const int N=1005,M=1<<16,mod=1e9+7;
int tt,n,f[2][M][3],tran1[20],tran2[20],tmp=0,ans[20],bit[M];
char s[20];
inline void trans(int sta,int a[]){
a[0]=0;
for(ri i=1;i<=n;++i)a[i]=a[i-1]+((sta>>(i-1))&1);
}
inline int inv_trans(int a[]){
int ret=0;
for(ri i=1;i<=n;++i)ret|=(a[i]-a[i-1])<<(i-1);
return ret;
}
inline int add(const int&a,const int&b){return a+b>=mod?a+b-mod:a+b;}
inline void update(int&a,const int&b){a=add(a,b);}
inline int max(const int&a,const int&b,const int&c){return a>b?(a>c?a:c):(b>c?b:c);}
inline void update(int pos,int sta,int len,char x,int upd){
trans(sta,tran1);
for(ri i=1;i<=n;++i)tran2[i]=max(tran2[i-1],tran1[i],tran1[i-1]+(x==s[i]));
int nsta=inv_trans(tran2);
update(f[pos][nsta][len],upd);
}
int main(){
scanf("%d%d%s",&tt,&n,s+1);
for(ri i=1,up=1<<n;i<up;++i)bit[i]=bit[i>>1]+(i&1);
f[0][0][0]=1;
for(ri up=1<<n;tt;--tt){
memset(f[tmp^1],0,sizeof(f[tmp^1]));
for(ri i=0;i<up;++i){
if(f[tmp][i][0]){
update(tmp^1,i,1,'N',f[tmp][i][0]);
update(tmp^1,i,0,'O',f[tmp][i][0]);
update(tmp^1,i,0,'I',f[tmp][i][0]);
}
if(f[tmp][i][1]){
update(tmp^1,i,1,'N',f[tmp][i][1]);
update(tmp^1,i,2,'O',f[tmp][i][1]);
update(tmp^1,i,0,'I',f[tmp][i][1]);
}
if(f[tmp][i][2]){
update(tmp^1,i,1,'N',f[tmp][i][2]);
update(tmp^1,i,0,'O',f[tmp][i][2]);
}
}
tmp^=1;
}
for(ri i=0,up=1<<n;i<up;++i)for(ri j=0;j<3;++j)update(ans[bit[i]],f[tmp][i][j]);
for(ri i=0;i<=n;++i)cout<<ans[i]<<'\n';
return 0;
}
str
对于每个碱基序列用kmpkmpkmp处理出failfailfail数组来进行dpdpdp转移即可。
代码:
#include<bits/stdc++.h>
#define ri register int
using namespace std;
const int N=10005,mod=1e9+7;
typedef long long ll;
inline int add(const int&a,const int&b){return a+b>=mod?a+b-mod:a+b;}
inline int dec(const int&a,const int&b){return a>=b?a-b:a-b+mod;}
inline int mul(const int&a,const int&b){return (ll)a*b%mod;}
inline void update(int&a,const int&b){a=add(a,b);}
int k,ans=0,Tt,n,f[2][N],tmp=0,m,fail[N];
char s[N],t[N];
int main(){
scanf("%d%s",&Tt,s+1),n=strlen(s+1);
for(ri i=0;i<=n;++i)f[0][i]=1;
for(ri tt;Tt;--Tt){
tmp^=1,memset(f[tmp],0,sizeof(f[tmp])),scanf("%d",&tt);
while(tt--){
scanf("%s",t+1),m=strlen(t+1);
for(ri i=1,j=0;i<m;++i){
while(j&&t[i+1]!=t[j+1])j=fail[j];
fail[i+1]=t[i+1]==t[j+1]?++j:0;
}
for(ri i=1,j=0;i<=n;++i){
while(j&&s[i]!=t[j+1])j=fail[j];
if(s[i]==t[j+1])++j;
if(j==m)update(f[tmp][i],f[tmp^1][i-m]);
}
}
}
for(ri i=0;i<=n;++i)update(ans,f[tmp][i]);
cout<<ans;
return 0;
}
xor
额这个题不是把可持久化01trie01trie01trie放到树上来差个分就完了吗?
代码:
#include<bits/stdc++.h>
#define ri register int
using namespace std;
const int N=1e5+5;
struct Trie{
int son[N*100][2],siz[N*100],tot;
Trie(){tot=0,memset(son,0,sizeof(son)),memset(siz,0,sizeof(siz));}
inline void insert(int &o,int las,int v){
int p=++tot;
o=p;
for(ri i=31,tmp;~i;--i){
tmp=(v>>i)&1;
siz[p]=siz[las]+1,son[p][tmp^1]=son[las][tmp^1],son[p][tmp]=++tot;
p=son[p][tmp],las=son[las][tmp];
}
siz[p]=siz[las]+1;
}
inline int query1(int pl,int pr,int v){
int ret=0;
for(ri i=31,tmp;~i;--i){
tmp=(v>>i)&1;
if(siz[son[pr][tmp^1]]!=siz[son[pl][tmp^1]])ret|=1<<i,pl=son[pl][tmp^1],pr=son[pr][tmp^1];
else pl=son[pl][tmp],pr=son[pr][tmp];
}
return ret;
}
inline int query2(int pa,int pb,int pc,int pd,int v){
int ret=0;
for(ri i=31,tmp;~i;--i){
tmp=(v>>i)&1;
if(siz[son[pa][tmp^1]]+siz[son[pb][tmp^1]]-siz[son[pc][tmp^1]]-siz[son[pd][tmp^1]]){
ret|=1<<i;
pa=son[pa][tmp^1],pb=son[pb][tmp^1],pc=son[pc][tmp^1],pd=son[pd][tmp^1];
}
else pa=son[pa][tmp],pb=son[pb][tmp],pc=son[pc][tmp],pd=son[pd][tmp];
}
return ret;
}
}T1,T2;
int n,q,rt1[N],rt2[N],siz[N],top[N],pred[N],tot=0,hson[N],dep[N],fa[N],num[N],a[N];
vector<int>e[N];
void dfs1(int p){
siz[p]=1;
for(ri i=0,v;i<e[p].size();++i){
if((v=e[p][i])==fa[p])continue;
fa[v]=p,dep[v]=dep[p]+1,dfs1(v),siz[p]+=siz[v];
if(siz[v]>siz[hson[p]])hson[p]=v;
}
}
void dfs2(int p,int tp){
top[p]=tp,pred[num[p]=++tot]=p;
T1.insert(rt1[p],rt1[fa[p]],a[p]);
if(!hson[p])return;
dfs2(hson[p],tp);
for(ri i=0,v;i<e[p].size();++i)if((v=e[p][i])!=fa[p]&&v!=hson[p])dfs2(v,v);
}
inline int lca(int x,int y){
while(top[x]^top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
x=fa[top[x]];
}
return dep[x]<dep[y]?x:y;
}
inline int read(){
int ans=0;
char ch=getchar();
while(!isdigit(ch))ch=getchar();
while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
return ans;
}
int main(){
n=read(),q=read();
for(ri i=1;i<=n;++i)a[i]=read();
for(ri i=1,u,v;i<n;++i)u=read(),v=read(),e[u].push_back(v),e[v].push_back(u);
dfs1(1),dfs2(1,1);
for(ri i=1;i<=n;++i)T2.insert(rt2[i],rt2[i-1],a[pred[i]]);
for(ri op,x,y,t;q;--q){
op=read(),x=read(),y=read();
if(op==1)cout<<T2.query1(rt2[num[x]-1],rt2[num[x]+siz[x]-1],y)<<'\n';
else t=lca(x,y),cout<<T1.query2(rt1[x],rt1[y],rt1[t],rt1[fa[t]],read())<<'\n';
}
return 0;
}
教科书般的亵渎
发现要维护这个东西:f(x,k)=∑i=1xikf(x,k)=\sum_{i=1}^xi^kf(x,k)=∑i=1xik
然后这个肯定是个kkk次多项式,于是拉格朗日插值把多项式求出来就完了。代码:
#include<bits/stdc++.h>
#define ri register int
using namespace std;
const int mod=1e9+7,N=105;
typedef long long ll;
inline int add(const int&a,const int&b){return a+b>=mod?a+b-mod:a+b;}
inline int dec(const int&a,const int&b){return a>=b?a-b:a-b+mod;}
inline int mul(const int&a,const int&b){return (ll)a*b%mod;}
inline void update(int&a,const int&b){a=add(a,b);}
inline int ksm(int a,int p){int ret=1;for(;p;p>>=1,a=mul(a,a))if(p&1)ret=mul(ret,a);return ret;}
ll n,a[N];
int m,k,f[N],inv[N];
inline int lagrange(int x,int n){
if(x<=k+2)return f[x];
int ret=0;
for(ri i=1,mult;i<=n;++i){
mult=f[i];
for(ri j=1;j<=n;++j){
if(i>j)mult=mul(mult,mul(inv[i-j],dec(x,j)));
if(i<j)mult=mul(mult,mul(mod-inv[j-i],dec(x,j)));
}
ret=add(ret,mult);
}
return ret;
}
int main(){
inv[1]=1;
for(ri i=2;i<=55;++i)inv[i]=mul(inv[mod-mod/i*i],mod-mod/i);
int tt;
scanf("%d",&tt);
while(tt--){
scanf("%lld%d",&n,&m),k=m+1;
for(ri i=1;i<=m;++i)scanf("%lld",&a[i]);
sort(a+1,a+m+1);
a[m+1]=n+1;
f[1]=1;
for(ri i=2;i<=k+2;++i)f[i]=add(f[i-1],ksm(i,k));
int ans=0;
for(ri i=0;i<=m;++i)for(ri j=i+1;j<=m+1;++j){
ans=add(ans,lagrange((a[j]-a[i]-1)%mod,k+2));
ans=dec(ans,lagrange((a[j-1]-a[i])%mod,k+2));
}
cout<<ans<<'\n';
}
return 0;
}
TJOI2018 简要题解的更多相关文章
- TJOI2018简要题解
Day1T1数学计算 按照时间轴建一棵线段树即可,复杂度为\(O(m \log m)\) #include <bits/stdc++.h> #define N 100005 #define ...
- Noip 2014酱油记+简要题解
好吧,day2T1把d默认为1也是醉了,现在只能期待数据弱然后怒卡一等线吧QAQ Day0 第一次下午出发啊真是不错,才2小时左右就到了233,在车上把sao和fate补掉就到了= = 然后到宾馆之后 ...
- Tsinghua 2018 DSA PA2简要题解
反正没时间写,先把简要题解(嘴巴A题)都给他写了记录一下. upd:任务倒是完成了,我也自闭了. CST2018 2-1 Meteorites: 乘法版的石子合并,堆 + 高精度. 写起来有点烦貌似. ...
- Codeforces 863 简要题解
文章目录 A题 B题 C题 D题 E题 F题 G题 传送门 简要题解?因为最后一题太毒不想写了所以其实是部分题解... A题 传送门 题意简述:给你一个数,问你能不能通过加前导000使其成为一个回文数 ...
- HNOI2018简要题解
HNOI2018简要题解 D1T1 寻宝游戏 题意 某大学每年都会有一次 Mystery Hunt 的活动,玩家需要根据设置的线索解谜,找到宝藏的位置,前一年获胜的队伍可以获得这一年出题的机会. 作为 ...
- JXOI2018简要题解
JXOI2018简要题解 T1 排序问题 题意 九条可怜是一个热爱思考的女孩子. 九条可怜最近正在研究各种排序的性质,她发现了一种很有趣的排序方法: Gobo sort ! Gobo sort 的算法 ...
- BJOI2018简要题解
BJOI2018简要题解 D1T1 二进制 题意 pupil 发现对于一个十进制数,无论怎么将其的数字重新排列,均不影响其是不是 \(3\) 的倍数.他想研究对于二进制,是否也有类似的性质. 于是他生 ...
- CQOI2018简要题解
CQOI2018简要题解 D1T1 破解 D-H 协议 题意 Diffie-Hellman 密钥交换协议是一种简单有效的密钥交换方法.它可以让通讯双方在没有事先约定密钥(密码)的情况下,通过不安全的信 ...
- AtCoder ExaWizards 2019 简要题解
AtCoder ExaWizards 2019 简要题解 Tags:题解 link:https://atcoder.jp/contests/exawizards2019 很水的一场ARC啊,随随便便就 ...
随机推荐
- 记录 Ext 日历月份选择控件bug解决过程结果
目录 背景 代码 背景 项目使用 Ext.NET 2.2.0.40838 , 对应 Ext JS4.2 版本. 结果 2017/3/31 号的时候偶然间点日历选择控件选择2月,10月等月份突然就跳到3 ...
- delphi combobox屏蔽鼠标滑动
//第1种方法 procedure TForm1.FormMouseWheel(Sender: TObject; Shift: TShiftState; WheelDelta: Integer; Mo ...
- SpringMVC之DispatcherServlet类图
DispatcherServlet类图 在IntelliJ IDEA 中打开其源码,然后右键查看Diagrams,工具会自动生成其类图. 可是直观的看出,DispatcherServlet本质上是Se ...
- 电商中的库存管理实现-mysql与redis
库存是电商系统的核心环节,如何做到不少卖,不超卖是库存关心的核心业务问题.业务量大时带来的问题是如何更快速的处理库存计算. 此处以最简模式来讨论库存设计. 以下内容只做分析,不能直接套用,欢迎 ...
- Android 开发 知晓各种id信息 获取线程ID、activityID、内核ID
/** * Returns the identifier of this process's user. * 返回此进程的用户的标识符. */ Log.e(TAG, "Process.myU ...
- 买二手iphone的建议
手机到手后一定要在第一时间把“按键开关.指纹解锁.指南针.照相机.话筒.听筒.手电筒.定位.WiFi”都测一遍. 环境有无wifi:imei:×××××序列号:××××× 外观和零件:1外观,1是否粗 ...
- Rabbitmq(7) confirm模式
1. //将通道设置为comfirm模式channel.confirmSelect(); // 消息确认if(!channel.waitForConfirms()){ System.out.print ...
- mui页面传值
以下代码全部在script标签内 一.通过mui.openWindow()打开新页面(若目标页面为已预加载成功的页面,则在openWindow方法中传递的extras参数无效): mui.openWi ...
- iosApp上传app遇到的问题
昨天上传了两个app,是由原来的app改版之后产生了新的app上传的,出现了几个问题现在记录一下. 1.证书配置问题:报错如下 解决办法:选择一个team即可.选择完team之后还是报错: 解决方法: ...
- FP数据库配置文件