zoukankan      html  css  js  c++  java
  • LOJ.#6468. 魔法[差分+树状数组]

    题意

    题目链接

    分析

    • 将询问差分并不断加入颜色。

    • 每种颜色,一个位置 (p) 都只会走到与之左右相邻的两个位置之一,分类讨论 ( m |A-B|) 的符号。

    • 实现可以使用树状数组。

    • 总时间复杂度为 (O(nlogn))

    代码

    #include<bits/stdc++.h>
    using namespace std;
    #define go(u) for(int i=head[u],v=e[i].to;i;i=e[i].last,v=e[i].to)
    #define rep(i,a,b) for(int i=a;i<=b;++i)
    #define pb push_back
    typedef long long LL;
    inline int gi() {
    	int x=0,f=1;
    	char ch=getchar();
    	while(!isdigit(ch))	{
    		if(ch=='-') f=-1;
    		ch=getchar();
    	}
    	while(isdigit(ch)) {
    		x=(x<<3)+(x<<1)+ch-48;
    		ch=getchar();
    	}
    	return x*f;
    }
    template<typename T>inline bool Max(T &a,T b) {
    	return a<b?a=b,1:0;
    }
    template<typename T>inline bool Min(T &a,T b) {
    	return b<a?a=b,1:0;
    }
    const int N=2e5 + 7;
    int n,Q;
    LL ans[N];
    struct querys{
    	int id,p,c;
    	querys(){}querys(int id,int p,int c):id(id),p(p),c(c){}
    };
    vector<int>G[N];
    vector<querys>q[N];
    struct BIT {
    	LL t1[N],t2[N];
    	int lowbit(int x) {
    		return x&-x;
    	}
    	void m1(int x,int y){for(int i=x;i<=n;i+=lowbit(i)) t1[i]+=y;}
    	void m2(int x,int y){for(int i=x;i<=n;i+=lowbit(i)) t2[i]+=y;}
    	pair<LL,int> query(int x){
    		LL r1=0;int r2=0;
    		for(int i=x; i; i-=lowbit(i)) r1+=t1[i],r2+=t2[i];
    		return make_pair(r1,r2);
    	}
    	void upd(int l,int r,int v) {
    		if(l>r) return;
    		m1(l,v),m1(r+1,-v);
    		m2(l,1),m2(r+1,-1);
    	}
    } A,B;
    int main(){
    	n=gi(),Q=gi();
    	rep(i,1,n) {
    		int c=gi();
    		G[c].pb(i);
    	}
    	
    	rep(i,1,Q) {
    		int p=gi(),l=gi(),r=gi();
    		q[l-1].pb(querys(i,p,-1));
    		q[r].pb(querys(i,p,1));
    	}
    	rep(i,1,n) {
    		for(int j=0; j<G[i].size(); ++j) {
    			if(!j)
    				B.upd(1,G[i][j]-1,G[i][j]);
    			if(j==(int)G[i].size()-1)
    				A.upd(G[i][j],n,G[i][j]);
    			else{
    				int mid=(G[i][j]+G[i][j+1])/2;
    				A.upd(G[i][j],mid,G[i][j]);
    				B.upd(mid+1,G[i][j+1]-1,G[i][j+1]);
    			}
    		}
    		for(auto v:q[i]) {
    			pair<LL,int> ra=A.query(v.p),rb=B.query(v.p);
    			ans[v.id]+=v.c*(1ll*ra.second*v.p-ra.first);
    			ans[v.id]+=v.c*(rb.first-1ll*rb.second*v.p);
    		}
    	}
    	rep(i,1,Q) printf("%lld
    ",ans[i]);
    	return 0;
    }
    
  • 相关阅读:
    allocation size overflow
    数据库隔离级别深入理解(ORACLE)
    查看Orcale数据里的表是否有变化
    意外发现抽象类的构造器
    C语言学习快速笔记
    由javascript的闭包引申到程序语言编译上的自由变量作用域的考量
    easyui的datagrid的列checkbox自定义增加disabled选项
    数据库连接不关闭造成的问题以及RowSet的使用
    Quartz的JobDetail没有触发器指向时会被删除的问题
    发现浏览器开发工具的一个小问题
  • 原文地址:https://www.cnblogs.com/yqgAKIOI/p/9878910.html
Copyright © 2011-2022 走看看