• [JSOI2018]列队


    题目

    这题好妙啊

    首先发现这是一道可怜题,又发现这道题是(t3),而且还是数据结构,怎么看都不是很可做的样子

    但是事实上这就是最可做的那一道题啊

    我们先胡乱发现一下,发现肯定存在某一个位置,这个位置左边的人都往右跑,这个位置右边的人都往左跑

    这非常显然啊,因为一旦另这个位置左边的一个人跨过这个位置往右边跑,那么就必须要右边的一个人再往左边跑,交换两个人只会使得答案更大

    于是我们考虑找到这个位置

    设这个位置为(x)

    (x)显然需要满足一个条件,(x-k+1=num)(num)(x)左边的人数,也就是左边得人刚好够把([k,x])填满,这样左边得人就不要往右边跑了

    我们简单移项,发现(x-num=k-1)

    分析一下(x-num),发现这个东西显然是单调不降的,因为(x)增加(1)(num)最多也就增加(1)

    于是我们我们要找的(x)位置肯定满足(x-num>=k-1)

    这个东西我们显然可以通过在主席树上二分找到

    二分的时候我们顺便求出这个位置左右所有有人的位置的坐标和就可以了

    代码

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #define re register
    #define LL long long
    const int maxn=5e5+6;
    const int M=22*maxn;
    inline int read() {
    	char c=getchar();int x=0;while(c<'0'||c>'9') c=getchar();
    	while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
    }
    int n,m,Q,cnt,K;
    int l[M],r[M],d[M];
    LL s[M],s1,s2;
    int rt[maxn];
    int change(int pre,int x,int y,int pos) {
    	int root=++cnt;
    	d[root]=d[pre]+1;s[root]=s[pre]+pos;
    	if(x==y) return root;
    	l[root]=l[pre],r[root]=r[pre];
    	int mid=x+y>>1;
    	if(pos<=mid) l[root]=change(l[pre],x,mid,pos);
    		else r[root]=change(r[pre],mid+1,y,pos);
    	return root;
    }
    int query(int p1,int p2,int x,int y,int k) {
    	if(x==y) return s1+=s[p2]-s[p1],x;
    	int now=d[l[p2]]-d[l[p1]];
    	int mid=x+y>>1;
    	if(mid-now-k>=K-1) return s2+=s[r[p2]]-s[r[p1]],query(l[p1],l[p2],x,mid,k);
    	return s1+=s[l[p2]]-s[l[p1]],query(r[p1],r[p2],mid+1,y,k+now);
    }
    inline LL sum(LL x,LL y) {
    	return (1ll*(y+1)*y-1ll*(x+1)*x)/2ll;
    }
    int main() {
    	n=read();Q=read();m=2e6;
    	for(re int i=1;i<=n;i++) rt[i]=change(rt[i-1],0,m,read());
    	int x,y;
    	while(Q--) {
    		x=read(),y=read(),K=read();s1=0;s2=0;
    		int t=query(rt[x-1],rt[y],0,m,0);
    		printf("%lld
    ",sum(K-1,t)-s1+s2-sum(t,K+y-x));
    	}
    	return 0;
    }
    
  • 相关阅读:
    分享我的2014年3月unity3d面试题与参考答案(转)
    Unity3D 面试ABC
    MiniJson解释Json字符串
    Unity3D研究之支持中文与本地文件的读取写入(转)
    unity3d--NGUI制作中文字体
    吊炸天之十步完全理解SQL
    mysql主从同步碰到的问题
    Redis 安装碰到问题
    在Centos系统下使用命令安装gnome图形界面程序
    centos7 网络问题
  • 原文地址:https://www.cnblogs.com/asuldb/p/10645387.html
Copyright © 2020-2023  润新知