【模板】数据结构
线段树:
#include<iostream> #define MAXN 101000 #define LL long long using namespace std; struct nond{ LL l,r,dis,flag; }tree[MAXN*4]; int N,M,a,b,c,Z; void tree_up(LL now){ tree[now].dis=tree[now*2].dis+tree[now*2+1].dis; } void tree_build(LL now,LL l,LL r){ tree[now].l=l; tree[now].r=r; if(l==r){ cin>>tree[now].dis; return; } LL mid=(tree[now].l+tree[now].r)/2; tree_build(now*2,l,mid); tree_build(now*2+1,mid+1,r); tree_up(now); } void tree_down(LL now){ tree[now*2].flag+=tree[now].flag; tree[now*2+1].flag+=tree[now].flag; tree[now*2].dis+=tree[now].flag*(tree[now*2].r-tree[now*2].l+1); tree[now*2+1].dis+=tree[now].flag*(tree[now*2+1].r-tree[now*2+1].l+1); tree[now].flag=0; return ; } void tree_change_many(LL now,LL l,LL r,LL x){ if(tree[now].l==l&&tree[now].r==r){ tree[now].dis+=x*(tree[now].r-tree[now].l+1); tree[now].flag+=x; return ; } if(tree[now].flag) tree_down(now); LL mid=(tree[now].l+tree[now].r)/2; if(r<=mid) tree_change_many(now*2,l,r,x); else if(l>mid) tree_change_many(now*2+1,l,r,x); else{ tree_change_many(now*2,l,mid,x); tree_change_many(now*2+1,mid+1,r,x); } tree_up(now); } LL tree_query_many(LL now,LL l,LL r){ if(tree[now].l==l&&tree[now].r==r){ return tree[now].dis; } if(tree[now].flag) tree_down(now); LL mid=(tree[now].l+tree[now].r)/2; if(r<=mid) return tree_query_many(now*2,l,r); else if(l>mid) return tree_query_many(now*2+1,l,r); else return tree_query_many(now*2,l,mid)+tree_query_many(now*2+1,mid+1,r); } int main(){ cin>>N>>M; tree_build(1,1,N); for(LL i=1;i<=M;i++){ cin>>Z; if(Z==1){ cin>>a>>b>>c; tree_change_many(1,a,b,c); } else if(Z==2){ cin>>a>>b; cout<<tree_query_many(1,a,b)<<endl; } } return 0; }
#include<cstdio> using namespace std; int n,p,a,b,m,x,ans; struct node { int l,r,w,f; }tree[400001]; inline void build(int k,int ll,int rr) { tree[k].l=ll,tree[k].r=rr; if(tree[k].l==tree[k].r) { scanf("%d",&tree[k].w); return; } int m=(ll+rr)/2; build(k*2,ll,m); build(k*2+1,m+1,rr); tree[k].w=tree[k*2].w+tree[k*2+1].w; } inline void down(int k) { tree[k*2].f+=tree[k].f; tree[k*2+1].f+=tree[k].f; tree[k*2].w+=tree[k].f*(tree[k*2].r-tree[k*2].l+1); tree[k*2+1].w+=tree[k].f*(tree[k*2+1].r-tree[k*2+1].l+1); tree[k].f=0; } inline void add(int k) { if(tree[k].l>=a&&tree[k].r<=b) { tree[k].w+=(tree[k].r-tree[k].l+1)*x; tree[k].f+=x; return; } if(tree[k].f) down(k); int m=(tree[k].l+tree[k].r)/2; if(a<=m) add(k*2); if(b>m) add(k*2+1); tree[k].w=tree[k*2].w+tree[k*2+1].w; } inline void ask(int k) { if(tree[k].l==tree[k].r) { ans=tree[k].w; return; } if(tree[k].f) down(k); int m=(tree[k].l+tree[k].r)/2; if(x<=m) ask(k*2); else ask(k*2+1); } int main() { scanf("%d",&n); build(1,1,n); scanf("%d",&m); for(int i=1;i<=m;i++) { scanf("%d",&p); if(p==1) { scanf("%d%d%d",&a,&b,&x); add(1); } else { scanf("%d",&x); ask(1); printf("%d\n",ans); } } }
#include<cstdio> using namespace std; int n,m,p,x,y,ans; struct node { int l,r,w; }tree[400001]; inline void build(int l,int r,int k) { tree[k].l=l;tree[k].r=r; if(l==r) { scanf("%d",&tree[k].w); return ; } int m=(l+r)/2; build(l,m,k*2); build(m+1,r,k*2+1); tree[k].w=tree[k*2].w+tree[k*2+1].w; } inline void add(int k) { if(tree[k].l==tree[k].r) { tree[k].w+=y; return; } int m=(tree[k].l+tree[k].r)/2; if(x<=m) add(k*2); else add(k*2+1); tree[k].w=tree[k*2].w+tree[k*2+1].w; } inline void sum(int k) { if(tree[k].l>=x&&tree[k].r<=y) { ans+=tree[k].w; return; } int m=(tree[k].l+tree[k].r)/2; if(x<=m) sum(k*2); if(y>m) sum(k*2+1); } int main() { scanf("%d",&n); build(1,n,1); scanf("%d",&m); for(int i=1;i<=m;i++) { scanf("%d%d%d",&p,&x,&y); ans=0; if(p==1) add(1); else { sum(1); printf("%d\n",ans); } } }
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define LL long long #define MAXN 100010 using namespace std; LL l[MAXN<<2],r[MAXN<<2],dis[MAXN<<2],falg1[MAXN<<2],falg2[MAXN<<2]; LL n,m,p; void up(LL now){ dis[now]=(dis[now<<1]+dis[now<<1|1])%p; } void build(LL now,LL ll,LL rr){ l[now]=ll; r[now]=rr; if(l[now]==r[now]){ cin>>dis[now]; return; } LL mid=(l[now]+r[now])>>1; build(now<<1,ll,mid); build(now<<1|1,mid+1,rr); up(now); } void down(LL now){ if(falg1[now]!=1){ falg2[now<<1]=falg2[now<<1]*falg1[now]%p; falg2[now<<1|1]=falg2[now<<1|1]*falg1[now]%p; dis[now<<1]=falg1[now]*dis[now<<1]%p; dis[now<<1|1]=falg1[now]*dis[now<<1|1]%p; falg1[now<<1]=falg1[now<<1]*falg1[now]%p; falg1[now<<1|1]=falg1[now<<1|1]*falg1[now]%p; falg1[now]=1; } if(falg2[now]){ dis[now<<1]=(dis[now<<1]+falg2[now]*(r[now<<1]-l[now<<1]+1)%p)%p; dis[now<<1|1]=(dis[now<<1|1]+falg2[now]*(r[now<<1|1]-l[now<<1|1]+1)%p); falg2[now<<1]=(falg2[now<<1]+falg2[now])%p; falg2[now<<1|1]=(falg2[now<<1|1]+falg2[now])%p; falg2[now]=0; } } void changec(LL now,LL ll,LL rr,LL k){ if(l[now]==ll&&r[now]==rr){ dis[now]=dis[now]*k%p; falg1[now]=falg1[now]*k%p; falg2[now]=falg2[now]*k%p; return; } if(falg1[now]!=0||falg2[now]) down(now); LL mid=(l[now]+r[now])>>1; if(rr<=mid) changec(now<<1,ll,rr,k); else if(ll>mid) changec(now<<1|1,ll,rr,k); else{ changec(now<<1,ll,mid,k); changec(now<<1|1,mid+1,rr,k); } up(now); } void changej(LL now,LL ll,LL rr,LL k){ if(l[now]==ll&&r[now]==rr){ dis[now]=(dis[now]+k*(r[now]-l[now]+1)%p)%p; falg2[now]+=k; return; } if(falg1[now]!=1||falg2[now]) down(now); LL mid=(l[now]+r[now])>>1; if(rr<=mid) changej(now<<1,ll,rr,k); else if(ll>mid) changej(now<<1|1,ll,rr,k); else{ changej(now<<1,ll,mid,k); changej(now<<1|1,mid+1,rr,k); } up(now); } LL query(LL now,LL ll,LL rr){ if(l[now]==ll&&r[now]==rr) return dis[now]%p; if(falg1[now]!=1||falg2[now]) down(now); LL mid=(l[now]+r[now])>>1; if(rr<=mid) return query(now<<1,ll,rr); else if(ll>mid) return query(now<<1|1,ll,rr); else return query(now<<1|1,mid+1,rr)+query(now<<1,ll,mid); } int main(){ cin>>n>>m>>p; build(1,1,n); memset(falg2,0,sizeof(falg2)); for(LL i=1;i<=n*4;i++) falg1[i]=1; for(LL i=1;i<=m;i++){ LL z,x,y,k; cin>>z>>x>>y; if(z==1){ cin>>k; changec(1,x,y,k); } else if(z==2){ cin>>k; changej(1,x,y,k); } else cout<<query(1,x,y)%p<<endl; } }
trie树
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define MAXN 500010 using namespace std; char s[50]; int n,m,tot,len,root; int sum[MAXN],tree[MAXN][30]; void insert(){ root=0; len=strlen(s); for(int i=0;i<len;i++){ int x=s[i]-'a'; if(!tree[root][x]) tree[root][x]=++tot; root=tree[root][x]; } sum[root]=1; } void find(){ root=0; len=strlen(s); for(int i=0;i<len;i++){ int x=s[i]-'a'; if(!tree[root][x]){ cout<<"WRONG"<<endl; return ; } root=tree[root][x]; } if(sum[root]==1){ sum[root]++; cout<<"OK"<<endl; return ; } else{ cout<<"REPEAT"<<endl; return ; } } int main(){ scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%s",s); insert(); } scanf("%d",&m); for(int i=1;i<=m;i++){ scanf("%s",s); find(); } }
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> using namespace std; int trie[400001][26],len,root,tot,sum[400001]; bool p; int n,m; char s[11]; void insert() { len=strlen(s); root=0; for(int i=0;i<len;i++) { int id=s[i]-'a'; if(!trie[root][id]) trie[root][id]=++tot; sum[trie[root][id]]++;//前缀后移一个位置保存 root=trie[root][id]; } } int search() { root=0; len=strlen(s); for(int i=0;i<len;i++) { int id=s[i]-'a'; if(!trie[root][id]) return 0; root=trie[root][id]; }//root经过此循环后变成前缀最后一个字母所在位置的后一个位置 return sum[root];//因为前缀后移了一个保存,所以此时的sum[root]就是要求的前缀出现的次数 } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { cin>>s; insert(); } scanf("%d",&m); for(int i=1;i<=m;i++) { cin>s; printf("%d\n",search()); } }
...
细雨斜风作晓寒。淡烟疏柳媚晴滩。入淮清洛渐漫漫。
雪沫乳花浮午盏,蓼茸蒿笋试春盘。人间有味是清欢。