zoukankan      html  css  js  c++  java
  • Comet OJ

    大意: 给定无向图, 点$i$点权$b_i$, 边$(x,y,z)$对序列贡献是把$A[b_x oplus b_y]$加上$z$.

    多组询问, 一共三种操作: 1. 修改点权. 2.修改边权. 3. 求序列$A$区间和.

    图按度数分块.

    对于轻点的贡献直接树状数组维护, 复杂度$O(17sqrt{m})$

    每一条重边选度数较大的重点$x$建一棵$01trie$, 询问$[L,R]$区间和就等价于求异或$b[x]$后范围在$[L,R]$的和, 复杂度$O(17sqrt{m})$.

    #include <iostream>
    #include <sstream>
    #include <algorithm>
    #include <cstdio>
    #include <math.h>
    #include <set>
    #include <map>
    #include <queue>
    #include <string>
    #include <string.h>
    #include <bitset>
    #define REP(i,a,n) for(int i=a;i<=n;++i)
    #define PER(i,a,n) for(int i=n;i>=a;--i)
    #define hr putchar(10)
    #define pb push_back
    #define lc (o<<1)
    #define rc (lc|1)
    #define mid ((l+r)>>1)
    #define ls lc,l,mid
    #define rs rc,mid+1,r
    #define x first
    #define y second
    #define io std::ios::sync_with_stdio(false)
    #define endl '
    '
    #define DB(a) ({REP(__i,1,n) cout<<a[__i]<<' ';hr;})
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pii;
    const int P = 998244353;
    const int N = 131080;
    const int S = 4000;
    int n, m, q, x[N], y[N], z[N];
    int b[N], deg[N], ID[N], E[N];
    vector<int> big, small[N];
    struct {
    	ll c[N];
    	void add(int x, int v) {
    		for (++x; x<N; x+=x&-x) c[x]+=v;
    	}
    	ll qry(int x) {
    		ll ret = 0;
    		for (++x; x; x^=x&-x) ret+=c[x];
    		return ret;
    	}
    } BIT;
    struct {
    	int T, tot;
    	struct {int ch[2],v;} a[N<<2];
    	void add(int &o, int d, int x, int v) {
    		if (!o) o = ++tot;
    		a[o].v = (a[o].v+v)%P;
    		if (d>=0) add(a[o].ch[x>>d&1],d-1,x,v);
    	}
    	void add(int x, int v) {
    		add(T,16,x,v);
    	}
    	ll qry(int o, int d, int x, int v) {
    		if (d<0) return a[o].v;
    		int f1 = x>>d&1, f2 = v>>d&1;
    		if (f2) return a[a[o].ch[f1]].v+qry(a[o].ch[!f1],d-1,x,v);
    		return qry(a[o].ch[f1],d-1,x,v);
    	}
    	ll qry(int x, int v) {
    		ll ret = qry(T,16,x,v);
    		return ret;
    	}
    } tr[100];
    void add(int id, int tp) {
    	if (E[id]) tr[E[id]].add(b[x[id]]^b[y[id]]^b[big[E[id]]],tp*z[id]);
    	else BIT.add(b[x[id]]^b[y[id]],tp*z[id]);
    }
    int qry(int x) {
    	if (x<0) return 0;
    	ll ans = BIT.qry(x);
    	for (int i=1; i<big.size(); ++i) {
    		ans += tr[i].qry(b[big[i]],x);
    	}
    	return ans%P;
    }
    
    int main() {
    	scanf("%d%d%d", &n, &m, &q);
    	REP(i,1,n) scanf("%d", b+i);
    	REP(i,1,m) {
    		scanf("%d%d%d", x+i, y+i, z+i);
    		++deg[x[i]],++deg[y[i]];
    	}
    	big.pb(0);
    	REP(i,1,n) if (deg[i]>=S) { 
    		ID[i] = ++*ID;
    		big.pb(i);
    	}
    	REP(i,1,m) {
    		if (ID[x[i]]&&deg[x[i]]>deg[y[i]]) {
    			E[i] = ID[x[i]];
    			small[y[i]].pb(i);
    		}
    		else if (ID[y[i]]) {
    			E[i] = ID[y[i]];
    			small[x[i]].pb(i);
    		}
    		else {
    			small[x[i]].pb(i);
    			small[y[i]].pb(i);
    		}
    		add(i, 1);
    	}
    	while (q--) {
    		int op,x,y;
    		scanf("%d%d%d", &op, &x, &y);
    		if (op==1) {
    			for (auto t:small[x]) add(t,-1);
    			b[x] = y;
    			for (auto t:small[x]) add(t,1);
    		}
    		else if (op==2) {
    			add(x,-1);
    			z[x] = y;
    			add(x,1);
    		}
    		else { 
    			int ans = (qry(y)-qry(x-1))%P;
    			if (ans<0) ans += P;
    			printf("%d
    ", ans);
    		}
    	}
    }
    
  • 相关阅读:
    垂死挣扎还是涅槃重生 -- Delphi XE5 公布会归来感想
    自考感悟,话谈备忘录模式
    [每日一题] OCP1z0-047 :2013-07-26 alter table set unused之后各种情况处理
    Java实现 蓝桥杯 算法提高 p1001
    Java实现 蓝桥杯 算法提高 拿糖果
    Java实现 蓝桥杯 算法提高 拿糖果
    Java实现 蓝桥杯 算法提高 求arccos值
    Java实现 蓝桥杯 算法提高 求arccos值
    Java实现 蓝桥杯 算法提高 因式分解
    Java实现 蓝桥杯 算法提高 因式分解
  • 原文地址:https://www.cnblogs.com/uid001/p/11257003.html
Copyright © 2011-2022 走看看