标签:
题意:给定一个序列ai,个数为n。再给出一系列w;对于每个w,求序列中,所有长度为w的连续子串中的权值和,子串权值为子串中不同数的个数
去了几个头文件,然后终于A了
1 #include<cstdio> 2 #include<cstring> 3 using namespace std; 4 #define ts printf("*****\n"); 5 #define cl(a) memset(a,0,sizeof(a)) 6 const int maxn=1000007; 7 long long dp[maxn]; 8 int dis[maxn]; //第i个数和前面最近相同的数的距离 例如1,2,1 d[3]=2 9 int r[maxn]; //和前面最近相同的数的距离为i的个数 10 int vis[maxn]; 11 int lastp[maxn]; //数i的最近上一个位置 12 int a[maxn]; 13 int dif[maxn]; //从n-i+1到n不同的数的个数 14 15 int main() 16 { 17 int i,j,k; 18 #ifndef ONLINE_JUDGE 19 freopen("1.in","r",stdin); 20 #endif 21 int n; 22 while(scanf("%d",&n)!=EOF) 23 { 24 if(n==0) break; 25 cl(lastp); 26 for(i=1;i<=n;i++) 27 { 28 scanf("%d",a+i); 29 dis[i]=i-lastp[a[i]]; 30 lastp[a[i]]=i; 31 } 32 cl(r); 33 for(i=1;i<=n;i++) 34 { 35 r[dis[i]]++; 36 } 37 cl(dif); 38 cl(vis); 39 int t=0; 40 for(i=n;i>0;i--) 41 { 42 if(!vis[a[i]]) 43 { 44 vis[a[i]]=1; 45 t++; 46 } 47 dif[n-i+1]=t; 48 } 49 int sum=n; 50 cl(dp); 51 dp[1]=n; 52 for(i=2;i<=n;i++) 53 { 54 dp[i]+=dp[i-1]-dif[i-1];//减掉最后一个区间的种类数 55 sum-=r[i-1]; 56 dp[i]+=sum; 57 } 58 int q,tt; 59 scanf("%d",&q); 60 while(q--) 61 { 62 scanf("%d",&tt); 63 printf("%I64d\n",dp[tt]); 64 } 65 } 66 return 0; 67 }
标签:
原文地址:http://www.cnblogs.com/cnblogs321114287/p/4470416.html