莫队的模板
1 struct node{ 2 int l,r,id; 3 }q[maxn]; 4 int cmp(node a,node b) { 5 return (belong[a.l] ^ belong[b.l]) ? belong[a.l] < belong[b.l] : ((belong[a.l] & 1) ? a.r < b.r : a.r > b.r); 6 } 7 8 n=strlen(s); 9 size = sqrt(n); 10 bnum = n / size; 11 for(int i = 1; i <= bnum; ++i) 12 for(int j = (i - 1) * size + 1; j <= i * size; ++j) { 13 belong[j] = i; 14 } 15 int ql = q[i].l, qr = q[i].r; 16 while(l < ql) now -= !--cnt[aa[l++]]; 17 while(l > ql) now += !cnt[aa[--l]]++; 18 while(r < qr) now += !cnt[aa[++r]]++; 19 while(r > qr) now -= !--cnt[aa[r--]]; 20 ans[q[i].id] = now;//now代表ql~qr之间有多少不同的数字
思路:
区间有多少种不同的字母,ql==qr yes ,三种以上yes,首尾不相等的yes其他都是no
莫队写法
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 #define il inline 5 #define it register int 6 #define lowbit(x) (x)&(-x) 7 #define mem(a,b) memset(a,b,sizeof(a)) 8 #define mod 1000000007 9 const int maxn=2e5+10; 10 char s[maxn]; 11 int cnt[maxn],belong[maxn],b[maxn],l=1,r=0,now=0,n,ql,qr,ls,ci; 12 struct node{ 13 int l,r,id,da; 14 }q[maxn]; 15 int cmp(node a,node b) { 16 return (belong[a.l] ^ belong[b.l]) ? belong[a.l] < belong[b.l] : ((belong[a.l] & 1) ? a.r < b.r : a.r > b.r); 17 } 18 int cmp1(node a,node b){ 19 return a.id<b.id; 20 } 21 il void add(int pos){ 22 if(!cnt[s[pos]-‘a‘]){++now;} 23 ++cnt[s[pos]-‘a‘]; 24 } 25 il void del(int pos){ 26 --cnt[s[pos]-‘a‘]; 27 if(!cnt[s[pos]-‘a‘])--now; 28 } 29 il int work(int q,int p){ 30 while(l<q)del(l++); 31 while(l>q)add(--l); 32 while(r<p)add(++r); 33 while(r>p)del(r--); 34 return now; 35 } 36 int main(){ 37 scanf("%s",s+1); 38 ls=strlen(s+1); 39 ci=sqrt(ls); 40 int ge=ls/ci; 41 for(it i=1;i<=ge;i++){ 42 for(it j=(i-1)*ci+1;j<=i*ci;j++){ 43 belong[j]=i; 44 } 45 } 46 scanf("%d",&n); 47 for(it i=0;i<n;i++){ 48 scanf("%d%d",&q[i].l,&q[i].r);q[i].id=i; 49 } 50 sort(q,q+n,cmp); 51 for(it i=0;i<n;i++){ 52 it ql=q[i].l,qr=q[i].r; 53 it z=work(ql,qr); 54 if(ql==qr){ 55 q[i].da=1; 56 } 57 else if(z>=3){ 58 q[i].da=1; 59 } 60 else if(s[ql]!=s[qr]){ 61 q[i].da=1; 62 } 63 else{ 64 q[i].da=-1; 65 } 66 } 67 sort(q,q+n,cmp1); 68 for(it i=0;i<n;i++){ 69 printf(q[i].da==1?"Yes\n":"No\n"); 70 } 71 return 0; 72 }
二维树状数组写法
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 #define il inline 5 #define it register int 6 #define lowbit(x) (x)&(-x) 7 #define mem(a,b) memset(a,b,sizeof(a)) 8 #define mod 1000000007 9 const int maxn=2e5+10; 10 char s[maxn]; 11 struct node{ 12 int tr[maxn]; 13 void inint(){ 14 memset(tr,0,sizeof(tr)); 15 } 16 void updata(int x,int y){ 17 for(int i=x; i<=maxn; i+=lowbit(i)){ 18 tr[i]+=y; 19 } 20 } 21 int geshu(int x,int y){ 22 int sum1=0,sum2=0; 23 for(int i=x; i>0; i-=lowbit(i)){ 24 sum1+=tr[i]; 25 } 26 for(int i=y; i>0; i-=lowbit(i)){ 27 sum2+=tr[i]; 28 } 29 return sum2-sum1; 30 } 31 } a[27]; 32 int main(){ 33 for(it i=0;i<26;i++){ 34 a[i].inint(); 35 } 36 scanf("%s",s+1); 37 int ls=strlen(s+1); 38 for(it i=1;i<=ls;i++){ 39 a[s[i]-‘a‘].updata(i,1); 40 } 41 it n,l,r; 42 scanf("%d",&n); 43 for(it i=0;i<n;i++){ 44 scanf("%d%d",&l,&r); 45 it z=0; 46 if(l==r || s[l]!=s[r]){ 47 printf("Yes\n");continue; 48 } 49 for(it i=0;i<26;i++){ 50 if(a[i].geshu(l,r)){ 51 z++; 52 } 53 } 54 if(z>=3){ 55 printf("Yes\n"); 56 } 57 else{ 58 printf("No\n"); 59 } 60 } 61 return 0; 62 }
这场打得有些自闭了
搞不懂c题,B题wa4发发现思路是错误的,最后在辉辉给出正确思路之后才过
D题就瞄了一眼,以为很难,赛后补题写了一个二维树状数组就过了,看了大佬的博客发现可以用莫队写,就试着用模板写
Codeforces Round #616 (Div. 2) D
原文:https://www.cnblogs.com/luoyugongxi/p/12256090.html