zoukankan      html  css  js  c++  java
  • bzoj2223[Coci 2009] PATULJCI

    题目链接:bzoj2223

    题目大意:

    给一个N个数的序列,M次询问,每次询问一个区间[l,r]内是否有某个数出现次数大于(r-l+1)/2,如果存在则输出这个数,否则输出no。


    题解:

    整体二分

    二分答案mid(就是那个数),如果某个询问区间里所有小于等于mid的数的个数都不大于(r-l+1)/2的话,那么该区间的答案一定大于mid,所以划分到[mid+1,r]这个区间上,反之相反。然后这个就跟之前一样用树状数组维护就好了。

    需要注意的一点是,最后当l=r时就不能再加小于等于mid的数了,必须要加入严格等于mid的数,这样才能判断是否有解


    【啊二分要先考虑有没有单调性啊,某大大好机智%%%怎么说看完豁然开朗

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define maxn 350000
    
    struct node
    {
    	int l,r,c,ans,tg;
    }q[maxn];
    int n,m,c[maxn],id[maxn];
    int tol[maxn],tor[maxn];
    int lowbit(int x) {return x&(-x);}
    void change(int x,int k)
    {
    	for (x;x<=n;x+=lowbit(x)) c[x]+=k;
    }
    int query(int x)
    {
    	int ret=0;
    	for (x;x>0;x-=lowbit(x)) ret+=c[x];
    	return ret;
    }
    void solve(int head,int tail,int l,int r)
    {
    	if (head>tail) return;
    	int i,lnum=0,rnum=0,mid=(l+r)>>1;
    	if (l==r)
    	{
    		for (i=head;i<=tail;i++)
    		  if (q[id[i]].tg==1 && q[id[i]].l==mid) change(q[id[i]].r,1);
    		  else if (q[id[i]].tg==2)
    		  {
    			  int now=query(q[id[i]].r)-query(q[id[i]].l-1);
    			  if (now>q[id[i]].c) q[id[i]].ans=l;
    			  else q[id[i]].ans=-1;
    		  }
    		for (i=head;i<=tail;i++)
    		  if (q[id[i]].tg==1 && q[id[i]].l==mid) change(q[id[i]].r,-1);
    		return;
    	}
    	for (i=head;i<=tail;i++)
    	  if (q[id[i]].tg==1)
    	  {
    		  if (q[id[i]].l<=mid) change(q[id[i]].r,1),tol[++lnum]=id[i];
    		  else tor[++rnum]=id[i];
    	  }
    	  else
    	  {
    		  int now=query(q[id[i]].r)-query(q[id[i]].l-1);
    		  if (now>q[id[i]].c) tol[++lnum]=id[i];
    		  else tor[++rnum]=id[i];
    	  }
    	for (i=head;i<=tail;i++)
    	  if (q[id[i]].tg==1 && q[id[i]].l<=mid) change(q[id[i]].r,-1);
    	for (i=0;i<lnum;i++) id[head+i]=tol[i+1];
    	for (i=0;i<rnum;i++) id[head+i+lnum]=tor[i+1];
    	solve(head,head+lnum-1,l,mid);
    	solve(head+lnum,tail,mid+1,r);
    }
    int main()
    {
    	//freopen("a.in","r",stdin);
    	//freopen("a.out","w",stdout);
    	int lim,t=0,i,x,y;
    	scanf("%d%d",&n,&lim);
    	for (i=1;i<=n;i++)
    	{
    		scanf("%d",&x);
    		id[++t]=t;q[t].tg=1;
    		q[t].l=x;q[t].r=i;
    		q[t].ans=-1;
    	}
    	scanf("%d",&m);
    	for (i=1;i<=m;i++)
    	{
    		scanf("%d%d",&x,&y);
    		id[++t]=t;q[t].tg=2;
    		q[t].c=(y-x+1)/2;
    		q[t].l=x;q[t].r=y;
    		q[t].ans=-1;
    	}
    	solve(1,t,1,lim);
    	for (i=1;i<=t;i++) 
    	 if (q[i].tg==2) 
    	 {
    		 if (q[i].ans!=-1) printf("yes %d
    ",q[i].ans);
    		 else printf("no
    ");
    	 }
    	return 0;
    }


  • 相关阅读:
    PhpStorm一次性折叠所有函数或者方法
    安装IntelliJ IDEA热部署tomcat插件JreBel
    mysql-master-ha
    mysql sys table
    Innodb 表修复(转)
    MySQL Binlog 【ROW】和【STATEMENT】选择(转)
    Innodb 存储引擎(转)
    MySQL 利用SQL线程对Binlog操作(转)
    针对跑MySQL的Linux优化【转】
    MySQL explain key_len 大小的计算
  • 原文地址:https://www.cnblogs.com/Euryale-Rose/p/6527813.html
Copyright © 2011-2022 走看看