Substrings 第37届ACM/ICPC 杭州赛区现场赛C题(hdu 4455)

来源:互联网 发布:中医方剂学大辞典软件 编辑:程序博客网 时间:2024/05/22 15:29

http://acm.hdu.edu.cn/showproblem.php?pid=4455

https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4384

题目大意就不多说了,官方的解法是dp,没太理解,自己想了一个直接点的方法,O(n)。

既然要计算所有贡献和,对于区间长度为k,假设集合中的元素全都相同,那么这个元素将会贡献给所有长度为k 的子区间。而事实上,所有元素不可能相同,因此就不可能贡献给所有长度为k 的子区间,那么思考,那些子区间是无法贡献的。假设集合中有序列 1......1,如果两个1的间隔为s,那么对于(k<s)的情况,总共有s-k+1个区间是没法贡献的。

而且,只要是任意的k<s,总存在区间是没法贡献的。对于一个k,

s1-k

s2-k

。。。
sum-k*cnt,记录s 的和,记录s>k的个数,就可以求出没法贡献的次数。再用总数减去就行了。有点抽象,能理解的理解理解。
#include<algorithm>#include<iostream>#include<fstream>#include<cstring>#include<cstdlib>#include<cstdio>#include<cmath>#include<string>#include<vector>#include<queue>#include<stack>#include<set>#include<map>#include<ctime>using namespace std;#define FOR(i,a,b)    for(int i=a;i<b;i++)#define FORD(i,a,b)    for(int i=a;i>b;i--)#define MST(a,num)    memset(a,num,sizeof(a))#define MCP(d,s)    memcpy(d,s,sizeof(s))#define WH(n)         while(scanf("%d", &n) != EOF)#define WHZ(n)         while(scanf("%d", &n) != EOF && n != 0)#define SCF(a)        scanf("%d",&a)#define PRF(a)        printf("%d",a)#define PRS(a)        printf("%s",a)#define PRFF(a)        printf("%d\n",a)#define PRSF(a)        printf("%s\n",a)#define PRFFU(a)        printf("%I64d\n",a)#define PI acos(-1)#define max3(a,b,c)     max(max(a,b),c)#define max4(a,b,c,d)     max(max(a,b),max(c,d))#define FORE(e,x) for(__typeof(x.begin()) e=x.begin(); e!=x.end(); e++) //foreach(it, ans ) cout<<*it<<" ";#define all(a) (a).begin(),(a).end() //sort(all(v));#define len(a) ((int)(a).size())#define pb push_back#define mk make_pair#define V(etype) vector<etype>typedef __int64 Uint;typedef vector<int> Vint;typedef pair<int,int>mypair;#define INF 0x3f3f3f3f#define eps 1e-9#define N 1000000+10int q[N];int head[N];int rt[N];int cnt[N];int num[N];Uint sum[N];int main(){int n,a,m;//freopen("data.in","r",stdin);//freopen("data2.out","w",stdout);while((cin>>n)&&n){MST(cnt,0);MST(sum,0);MST(rt,-1);MST(head,-1);q[0]=0;FOR(i,0,n){    SCF(num[i]);    if(head[num[i]]==-1)q[++q[0]]=num[i];    rt[i]=head[num[i]];    head[num[i]]=i;}FOR(i,1,q[0]+1){rt[n]=head[q[i]];    for(int j=n;j!=-1;j=rt[j]){        cnt[j-rt[j]]--;        sum[j-rt[j]]-=j-rt[j];        cnt[0]++;        sum[0]+=j-rt[j];    }}FOR(i,1,n){sum[i]+=sum[i-1],cnt[i]+=cnt[i-1];//ret[i]=(n-i+1)*q[0]-(sum[i]-num[i]*cnt[i]);}Uint s1,s2;SCF(m);while(m--){    SCF(a);if(!a)PRSF("0\n");else{    s1=(n-a+1);    s1*=q[0];    s2=a;    s2*=cnt[a];    s2=sum[a]-s2;    PRFFU(s1-s2);}}}return 0;}/*71 1 2 3 4 4 531 2 371 1 2 3 4 4 541 2 3 0*/



原创粉丝点击