hdu 6058 Kanade's sum

来源:互联网 发布:学完php在学java好学吗 编辑:程序博客网 时间:2024/05/19 08:39
/*     计算每个数的贡献,找到左边k-1个大于 pi的,右边 大于pi 的, 所有有贡献的区间都在这个范围内。用链表维护位置,结束后删除pi, 从小到大 枚举,可以保证链表中的数 >=pi; */ #include<iostream>#include<algorithm>#include<cstdio>using namespace std;typedef long long ll;const int mod =1e9+7;const int Size = 510000;int pre[Size],nxt[Size],pos[Size];inline void read(int &x){    x=0;char p=getchar();    while(!(p<='9'&&p>='0')) p=getchar();    while(p<='9'&&p>='0')x*=10,x+=p-48,p=getchar();}int main(){int t,n,k;read(t);while(t--){int p=0,x;read(n);read(k);for(int i=1;i<=n;i++) {    read(x); pos[x]=i; nxt[p]=x; pre[x]=p; p=x; } nxt[x]=n+1;pos[n+1]=n+1; ll ans=0; for(int i=1;i<=n;i++)   {      p=i;      int cnt=1,p1=i;   ll sum=0;      while(cnt<k&&pre[p]) p=pre[p],cnt++;      while(cnt<k&&nxt[p1]!=n+1) p1=nxt[p1],cnt++;      if(cnt<k) continue;      for(;p!=nxt[i];p=nxt[p])        {        int l1=(pos[p]-pos[pre[p]]);        int r1=(pos[nxt[p1]]-pos[p1]);        sum +=l1*r1;        p1=nxt[p1];        if(p1==n+1) break;         }pre[nxt[i]]=pre[i];nxt[pre[i]]=nxt[i]; ans +=(ll)sum*i;   }   printf("%lld\n",ans);}return 0;}

原创粉丝点击