链接:戳这里
10 1
思路:cf上有一道类似这样的题,我们用数组H[i],H[j]分别记录当前更换的行i,j的原始行j,i。同理列也是如此
对于当前的行x增加的y值,也直接加到原始的行H[x]上去(列也是一样)
接着N*M处理出 当前的i行j列所对应的值也就是原始的H[i]行L[j]列所对应的值
对应的行列所增加的值也直接增加原始的H[i],L[j]的值
这种类型的题肯定是抓住原始的i,j不放,然后换种方式去更新值
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<string> #include<vector> #include <ctime> #include<queue> #include<set> #include<map> #include<stack> #include<iomanip> #include<cmath> #define mst(ss,b) memset((ss),(b),sizeof(ss)) #define maxn 0x3f3f3f3f #define MAX 1000100 ///#pragma comment(linker, "/STACK:102400000,102400000") typedef long long ll; typedef unsigned long long ull; #define INF (1ll<<60)-1 using namespace std; ll a[1010][1010],anw[1010][1010]; int H[1010],L[1010]; ll Hval[1010],Lval[1010]; int n,m,q; int main(){ int T; scanf("%d",&T); while(T--){ scanf("%d%d%d",&n,&m,&q); mst(Hval,0); mst(Lval,0); mst(anw,0); for(int i=1;i<=n;i++) H[i]=i; for(int i=1;i<=m;i++) L[i]=i; for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ scanf("%I64d",&a[i][j]); } } while(q--){ int f,x,y; scanf("%d%d%d",&f,&x,&y); if(f==1) { swap(H[x],H[y]); } else if(f==2){ swap(L[x],L[y]); } else if(f==3){ Hval[H[x]]+=y; } else { Lval[L[x]]+=y; } } for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ anw[i][j]+=a[H[i]][L[j]]; anw[i][j]+=Hval[H[i]]; anw[i][j]+=Lval[L[j]]; } } for(int i=1;i<=n;i++){ for(int j=1;j<m;j++){ printf("%I64d ",anw[i][j]); } printf("%I64d\n",anw[i][m]); } } return 0; } /* 1 2 2 8 1 2 3 4 1 1 2 3 1 5 2 1 2 3 2 4 1 1 2 3 1 5 2 1 2 3 2 4 */<strong> </strong>
思路:
枚举当前的位置i到位置j内有多少不同的之母num
发现i,j的值都是可以线性滚动过去的
也就是找到以区间[i,j]为基础的贡献值(n-j+1)
区间[i,j]表示为以i开头到最近的j内至少有k个不同的字母
然后处理当前的字母s[j]插进来是不是正好使得不同字母达到k个,然后对应的i踢掉一个再判断
具体看代码
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<string> #include<vector> #include <ctime> #include<queue> #include<set> #include<map> #include<stack> #include<iomanip> #include<cmath> #define mst(ss,b) memset((ss),(b),sizeof(ss)) #define maxn 0x3f3f3f3f #define MAX 1000100 ///#pragma comment(linker, "/STACK:102400000,102400000") typedef long long ll; typedef unsigned long long ull; #define INF (1ll<<60)-1 using namespace std; string s; int a[1000100]; int vis[33],num[1000100]; int main(){ int T,k; scanf("%d",&T); while(T--){ mst(num,0); mst(vis,0); mst(a,0); cin>>s; scanf("%d",&k); int n=s.size(); for(int i=0;i<n;i++) a[i+1]=s[i]-'a'+1; ll ans=0; int i=1,j=0,num=0; for(i=1;i<=n;i++){ while(j+1<=n && num<k){ j++; vis[a[j]]++; if(vis[a[j]]==1) num++; } if(num==k){ ans+=n-j+1; } vis[a[i]]--; if(vis[a[i]]==0) num--; } printf("%I64d\n",ans); } return 0; }<strong> </strong>