• (分块)GukiZ and GukiZiana CodeForces


    题意:

    给你一段序列,并且有两种操作

    操作①:将序列中从l-r每个元素加上x

    操作②:在序列中找到ai=aj=y,j-i的最大值,如果找不到则输出-1

    思路:

    直接分块暴力即可

    对于区间加,普通标记加暴力即可

    对于找最大值,直接在每个块中二分找y,找不到即为-1

    #include<iostream>
    #include<algorithm>
    #include<set>
    #include<cmath>
    #include<vector>
     using namespace std;
     typedef long long ll;
     const int maxn=5e5+10;
     ll n,blo,tot;
     ll a[maxn];//bl数组记录属于哪个块 
     int bel[maxn],m;
     ll tag[maxn];//维护区间加标记 
     vector <ll> vc[maxn]; 
     void build()
     {
     	blo=sqrt(n);
     	tot=n/blo;
     	if(n%blo) tot++;
     	for(int i=1;i<=n;i++){
     		bel[i]=(i-1)/blo+1;
     		vc[bel[i]].push_back(a[i]);
    	 }
    	for(int i=1;i<=tot;i++)
    		sort(vc[i].begin(),vc[i].end());
     }
    void reset(int x)
    {
    	vc[x].clear();
    	for(int i=(x-1)*blo+1;i<=x*blo;i++)
    		vc[x].push_back(a[i]);
    	sort(vc[x].begin(),vc[x].end());
    }
     void add(int l,int r,int x)
     {
     	int b1=bel[l],b2=bel[r];
     	if(b1==b2){
     		for(int i=l;i<=r;i++)
     			a[i]+=x;
    		reset(b1); 
    	 }
     	else{
     		for(int i=l;i<=b1*blo;i++)
     			a[i]+=x;
     		reset(b1);
     		for(int i=b1+1;i<b2;i++)
     			tag[i]+=x;
     		for(int i=(b2-1)*blo+1;i<=r;i++) a[i]+=x;
    			reset(b2);
    	 }
     }
     int query(int y)
     {
     	int l=0,r=0;
     	for(int i=1;i<=tot;i++){
     		int pos=lower_bound(vc[i].begin(),vc[i].end(),y-tag[i])-vc[i].begin();
     		if(y-tag[i] == vc[i][pos]){
     			for(int j=(i-1)*blo+1;j<=i*blo;j++)
     				if(a[j]+tag[i]==y){
     					l=j;
     					break;
    				 }
     			break;
    		 }
    	 }
    	if(l==0) return -1;
     	for(int i=tot;i>=1;i--){
     		int pos=lower_bound(vc[i].begin(),vc[i].end(),y-tag[i])-vc[i].begin();
     		if(y-tag[i] == vc[i][pos]){
     			for(int j=i*blo;j>(i-1)*blo;j--)
     				if(a[j]+tag[i]==y){
     					r=j;
     					break;
    		  }
    		break;
    		}
    	 }
    	return r-l;
     }
    
     int main()
     {
     	int q,l,r,y,op;
     	scanf("%lld%d",&n,&q);
     	for(int i=1;i<=n;i++)
     		scanf("%d",&a[i]);
     	build(); 
    	for(int i=1;i<=q;i++){
    		scanf("%d",&op);
    		if(op==1){
    			scanf("%d%d%d",&l,&r,&y);
    			add(l,r,y);
    		}
    		else{
    			scanf("%d",&y);
    			printf("%d
    ",query(y));
    		}
    	}
    	return 0; 
     }
    

      

     

  • 相关阅读:
    js替换问题replace和replaceAll
    CSS截取标题...
    MVC FormCollection collection
    IE和FF判断浏览器是否安装了flash插件
    Uploadify上传插件不兼容FF、Chrome等Netscape浏览器
    jquery错误消息: “Date”未定义,“String”未定义
    正则表达式取出指定字符窜之间的字符窜
    WPF 开发前学习(二)
    WPF 中的树应用
    WCF 数据传输遇到的问题
  • 原文地址:https://www.cnblogs.com/overrate-wsj/p/12169176.html
Copyright © 2020-2023  润新知