• BZOJ 3110([Zjoi2013]K大数查询-区间第k大[段修改,在线]-树状数组套函数式线段树)


    3110: [Zjoi2013]K大数查询

    Time Limit: 20 Sec   Memory Limit: 512 MB
    Submit: 418   Solved: 235
    [ Submit][ Status][ Discuss]

    Description

    有N个位置,M个操作。操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c
    如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数是多少。

    Input

    第一行N,M
    接下来M行,每行形如1 a b c或2 a b c

    Output

    输出每个询问的结果

    Sample Input

    2 5
    1 1 2 1
    1 1 2 2
    2 1 1 2
    2 1 1 1
    2 1 2 3

    Sample Output


    1
    2
    1

    HINT

     



    N,M<=50000,N,M<=50000

    a<=b<=N

    1操作中abs(c)<=N

    2操作中abs(c)<=Maxlongint

     

    Source

     
    [ Submit][ Status][ Discuss]

    本来上一次就偷懒。。。、

    话说写线段树不写离散化可不是一个好习惯。。。

    所以我果断加上了离散。。。

    ================Cute 分割线 ============================

    其实这题可以直接拆数,zkw线段树区间修改法解决数组修改。。。

    但是做到一半就把自己绕晕了....我X注定NC

    话说这题要离散的是插入的数——所以拆的于是插入的数(具体来说,S1:头尾插1个,S2:头尾差x*i个)

    然后总算A了……

    我的人生都浪费在DeBug上了么......

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<functional>
    #include<cmath>
    #include<cctype>
    #include<map>
    using namespace std;
    #define For(i,n) for(int i=1;i<=n;i++)
    #define Rep(i,n) for(int i=0;i<n;i++)
    #define Fork(i,k,n) for(int i=k;i<=n;i++)
    #define ForD(i,n) for(int i=n;i;i--)
    #define Forp(x) for(int p=pre[x];p;p=next[p])
    #define RepD(i,n) for(int i=n;i>=0;i--)
    #define MEM(a) memset(a,0,sizeof(a))
    #define MEMI(a) memset(a,127,sizeof(a))
    #define MEMi(a) memset(a,128,sizeof(a))
    #define MAXN (50000+10)
    #define MAXM (50000+10)
    #define MINAi (1)
    #define MAXAi (size)
    #define maxlongint (2147483647)
    int n,m;
    int a2[MAXN],size=0;
    struct node
    {
    	int ch[2],c;
    	node():c(0){ch[0]=ch[1]=0;}
    }q[10000000];
    int root[MAXN<<1],tail=0;
    void inc(int &x,long long l,long long r,int c,int d)
    {
    	if (!x) x=++tail;
    	q[x].c+=d;
    	if (l==r) return;
    	long long m=l+r>>1;
    	if (c<=m) inc(q[x].ch[0],l,m,c,d);
    	else inc(q[x].ch[1],m+1,r,c,d);	
    }
    void update(int x,int c,int d)
    {
    	for(int i=x;i<=n;i+=i&(-i)) inc(root[i],MINAi,MAXAi,c,d);
    	for(int i=x;i<=n;i+=i&(-i)) inc(root[i+n],MINAi,MAXAi,c,d*x);
    }
    int ans[MAXN][2],ans_end[2],ans_siz[2];
    void qur(int x)
    {
    	Rep(p,2)
    		for(int i=x;i;i-=i&(-i)) ans[++ans_siz[p]][p]=root[i+p*n];
    }
    void turn(bool c)
    {
    	Rep(p,2)
    		For(i,ans_siz[p])
    			ans[i][p]=q[ans[i][p]].ch[c];
    }
    struct comm
    {
    	int p,a,b,c;
    	comm(){}
    }ask[MAXM];
    map<long long ,int> h;
    int main()
    {
    //	freopen("bzoj3110.in","r",stdin);
    //	freopen(".out","w",stdout);
    	scanf("%d%d",&n,&m);
    	For(i,m) {scanf("%d%d%d%d",&ask[i].p,&ask[i].a,&ask[i].b,&ask[i].c);if (ask[i].p==1) a2[++size]=ask[i].c;}
    	sort(a2+1,a2+1+size);
    	size=unique(a2+1,a2+1+size)-(a2+1);
    	For(i,size) h[a2[i]]=i;
    	For(i,m)
    	{
    		if (ask[i].p==1) ask[i].c=h[ask[i].c];
    	}
    	
    	For(i,m)
    	{
    		int p;
    		p=ask[i].p;
    		if (p==1)
    		{
    			int l,r,c;
    			l=ask[i].a,r=ask[i].b,c=ask[i].c;
    			update(l,c,1);update(r+1,c,-1);
    		}
    		else
    		{
    			long long l,r,k,l1,r1;
    			l=ask[i].a,r=ask[i].b,k=ask[i].c;l1=l,r1=r;
    			ans_siz[0]=ans_siz[1]=0;
    			qur(r);memcpy(ans_end,ans_siz,sizeof(ans_end));qur(l-1);
    			l=MINAi,r=MAXAi;
    			while (l<r)
    			{
    				long long s[2]={0},m=(l+r)>>1;
    				Rep(p,2)
    				{
    					For(i,ans_end[p]) s[p]+=q[q[ans[i][p]].ch[1]].c;
    					long long p1=s[p];s[p]=0;
    					Fork(i,ans_end[p]+1,ans_siz[p]) s[p]+=q[q[ans[i][p]].ch[1]].c;
    					if (p==0) s[p]=p1*(r1+1)-s[p]*l1;
    					else s[p]=p1-s[p];
    				}
    				long long tot=s[0]-s[1];
    			//	cout<<tot<<' ';
    				if (k<=tot) l=m+1,turn(1);else r=m,k-=tot,turn(0);				
    			}
    			printf("%d
    ",a2[l]);
    		}
    	}	
    	return 0;
    }






  • 相关阅读:
    如何在 Linux 虚拟机上扩展根文件系统
    Linux 虚拟机中配置 GNOME + VNC
    在 Linux 中使用 Azure Premium 存储的基本优化指南
    如何为运行的 ARM Linux 启用 LAD2.3 版本的诊断扩展
    不要在构造函数中抛出异常
    vtk java
    富文本keditor的一些使用问题
    几个问题
    Java并发编程(十四)并发容器类
    FreeBSD编译安装emacs,不要用ports
  • 原文地址:https://www.cnblogs.com/dyllove98/p/3146995.html
Copyright © 2020-2023  润新知