zoukankan      html  css  js  c++  java
  • cdcqの省选膜你赛

    cdcqの省选膜你赛

    比赛当天因为在杠hnoi2016的大数据结构没有参加,今天补了一下。挺好玩的虽然不看一句话题意的话真的卡读题

    此生无悔入东方,来世愿生幻想乡


    2651. 新史「新幻想史 -现代史-」

    一句话题意:
    有一个长度为n的整数序列,共m个时刻,在每个时刻都有一个操作,如果是询问操作则询问指定时刻一段区间的和,如果是修改操作则使修改指定时刻到当前时刻的所有时刻一段区间全部增加一个数,另一段区间全部减少一个数


    令t代表指定时间

    询问和修改拆开
    显然的偏序关系:

    [id' < id, t' le t, x' le x ]

    CDQ分治,x那一维的前缀加和前缀求和树状数组搞就行了

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    typedef long long ll;
    const int N=2e5+5;
    inline int read(){
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    
    int n, m, a[N], d, l, r, t; ll s[N], ans[N];
    char op[3];
    struct meow{
    	int id, t, x, type, d, qid;
    	bool operator <(const meow &a) const {return t == a.t ? type > a.type : t < a.t;}
    	void print(int a) {
    		printf("q %d  %d  (%d, %d, %d)  %d   %d
    ", a, type, id, t, x, d, qid);
    	}
    } q[N], _q[N];
    int tot, Q;
    inline void divide(int type) {
    	if(type == 0) {
    		l=read(); r=read(); t=read(); Q++;
    		tot++; q[tot] = (meow){tot, t, l-1, 0, -1, Q};
    		tot++; q[tot] = (meow){tot, t, r  , 0, 1, Q};
    		ans[Q] += s[r] - s[l-1];
    	} else {
    		l=read(); r=read(); d=read();
    		tot++; q[tot] = (meow){tot, 0, l-1, 1, d, 0};
    		tot++; q[tot] = (meow){tot, 0, r  , 1, -d, 0};
    		l=read(); r=read(); d=read();
    		tot++; q[tot] = (meow){tot, 0, l-1, 1, -d, 0};
    		tot++; q[tot] = (meow){tot, 0, r  , 1, d, 0};
    		t=read();
    		q[tot].t = q[tot-1].t = q[tot-2].t = q[tot-3].t = t;
    	}
    }
    
    namespace bit {
    	struct meow {
    		ll c[N]; int t[N], T;
    		inline void add(int p, ll d) {
    			for(; p<=n; p+=p&-p) {
    				if(t[p] != T) t[p] = T, c[p] = d;
    				else c[p] += d;
    			}
    		}
    		inline ll sum(int p) {
    			ll ans=0; 
    			for(; p; p-=p&-p) if(t[p] == T) ans += c[p];
    			return ans;
    		}
    		inline ll sum(int l, int r) {return sum(r) - sum(l-1);}
    	}c1, c2;
    	inline void init() {c1.T++; c2.T++;}
    	inline void add(int l, int r, ll d) { //printf("add [%d, %d] %lld
    ", l, r, d);
    		c1.add(l, d); c1.add(r+1, -d);
    		c2.add(l, l*d); c2.add(r+1, -(r+1)*d);
    	}
    	inline ll sum(int l, int r) { //printf("sum [%d, %d]
    ", l, r);
    		return (r-l+1) * c1.sum(l) + (r+1) * c1.sum(l+1, r) - c2.sum(l+1, r);
    	}
    } using bit::add; using bit::sum;
    
    void cdq(int l, int r) { 
    	if(l == r) return; //printf("
    ----------cdq [%d, %d]
    ", l, r);
    	int mid = (l+r)>>1;
    	cdq(l, mid); cdq(mid+1, r);
    	int p1=l, p2=mid+1, p=l;
    	bit::init();
    	//for(int i=l; i<=r; i++) q[i].print(i);
    	while(p1<=mid || p2<=r) {
    		if(p2>r || (p1<=mid && q[p1]<q[p2])) { //printf("p1 %d  %d
    ", p1, q[p1].id);
    			if(q[p1].type) add(1, q[p1].x, q[p1].d);
    			_q[p++] = q[p1++];
    		} else {
    			if(!q[p2].type) ans[ q[p2].qid ] += q[p2].d * sum(1, q[p2].x);// printf("QwQ  %d  %lld
    ", q[p2].d, sum(1, q[p2].x));;
    			_q[p++] = q[p2++];
    		}
    	}
    	for(int i=l; i<=r; i++) q[i] = _q[i];// q[i].print(i);
    	//printf("----------end [%d, %d]
    
    ", l, r);
    }
    
    int main() {
    	//freopen("in", "r", stdin);
    	freopen("cdcq_a.in", "r", stdin);
    	freopen("cdcq_a.out", "w", stdout);
    	n=read(); m=read();
    	for(int i=1; i<=n; i++) a[i]=read(), s[i] = s[i-1] + a[i];
    	for(int i=1; i<=m; i++) {
    		scanf("%s", op);
    		if(op[0] == 'Q') divide(0);
    		else divide(1);
    	}
    	//for(int i=1; i<=tot; i++) q[i].print(i);
    	cdq(1, tot);
    	for(int i=1; i<=Q; i++) printf("%lld
    ", ans[i]);
    }
    
    

    2652. 秘术「天文密葬法」

    一句话题意:

    给个树,第i个点有两个权值ai和bi,现在求一条长度为m的路径,使得Σai/Σbi最小


    裸分数规划... 求路径用点分治

    然后m=1肯定是单点取最小呀

    调试过程出现各种玄学问题

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    typedef long long ll;
    const int N=2e5+5, INF=1e9;
    inline int read(){
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    
    int n, m, a[N], b[N]; double val[N];
    struct edge{int v, ne;} e[N<<1];
    int cnt=1, h[N];
    inline void ins(int u, int v) {
    	e[++cnt]=(edge){v, h[u]}; h[u]=cnt;
    	e[++cnt]=(edge){u, h[v]}; h[v]=cnt;
    }
    
    namespace tr {
    	int size[N], root, vis[N], f[N], all, ans;
    	void dfsr(int u, int fa) { 
    		size[u]=1; f[u] = 0;
    		for(int i=h[u];i;i=e[i].ne) 
    			if(!vis[e[i].v] && e[i].v != fa) {
    				dfsr(e[i].v, u);
    				size[u] += size[e[i].v];
    				f[u] = max(f[u], size[e[i].v]);
    			}
    		f[u] = max(f[u], all-size[u]);
    		if(f[u] < f[root]) root = u;
    	}
    
    	double d[N]; int st[N], top;
    	void dfscal(int u, int fa, int deep, double now, int rt) {
    		if(d[m-deep+1] + now - val[rt] < 0) ans=1; 
    		for(int i=h[u];i;i=e[i].ne)
    			if(!vis[e[i].v] && e[i].v != fa) dfscal(e[i].v, u, deep+1, now + val[e[i].v], rt);
    	}
    	void dfsadd(int u, int fa, int deep, double now, int rt) {
    		if(now < d[deep]) d[deep] = now, st[++top] = deep;
    		for(int i=h[u];i;i=e[i].ne)
    			if(!vis[e[i].v] && e[i].v != fa) dfsadd(e[i].v, u, deep+1, now + val[e[i].v], rt);
    	}
    	bool dfs(int u) { //printf("dfs %d
    ", u);
    		vis[u]=1;
    		d[1] = val[u];
    		for(int i=h[u];i;i=e[i].ne) if(!vis[e[i].v]) {
    			dfscal(e[i].v, u, 2, val[u] + val[e[i].v], u); 
    			dfsadd(e[i].v, u, 2, val[u] + val[e[i].v], u);
    		}
    		while(top) d[ st[top--] ] = 1e18;
    		if(ans) return true;
    		for(int i=h[u];i;i=e[i].ne)
    			if(!vis[e[i].v]) { 
    				all = size[e[i].v]; root=0; dfsr(e[i].v, 0);
    				if(dfs(root)) return true;
    			}
    		return false;
    	}
    
    	bool check(double mid) {
    		for(int i=1; i<=n; i++) val[i] = a[i] - mid*b[i], vis[i] = 0, d[i] = 1e18;
    		f[0]=INF; ans=0; top=0;
    		all=n; root=0; dfsr(1, 0);
    		return dfs(root);
    	}
    }
    
    void solve() {
    	double l=0, r=2e10;
    	while(r-l > 1e-4) {
    		double mid = (l+r)/2.0;
    		if(tr::check(mid)) r=mid;
    		else l=mid;
    	}
    	if(l > 2e10 - 1e-3) puts("-1");
    	else printf("%.2lf", l);
    }
    int main() {
    	freopen("in", "r", stdin);
    	//freopen("cdcq_b.in", "r", stdin);
    	//freopen("cdcq_b.out", "w", stdout);
    
    	n=read(); m=read();
    	for(int i=1; i<=n; i++) a[i]=read();
    	for(int i=1; i<=n; i++) b[i]=read();
    	if(m == -1) {
    		double ans = INF;
    		for(int i=1; i<=n; i++) ans = min(ans, (double) a[i] / b[i]);
    		printf("%.2lf
    ", ans);
    		return 0;
    	}
    	for(int i=1; i<n; i++) ins(read(), read());
    	//printf("%d
    ", tr::check(0.45));
    	solve();
    }
    
    

    2653. 源符「厌川的翡翠」

    一句话题意:

    给个仙人掌,仙人掌上每个点都能填入[1,t]中的整数,第i个点填j会获得收益v[i][j],求一个最小的c,使得存在一种填数的方案,满足没有两个用边相邻的点填的数差值超过c且所有点的收益和不超过w


    二分c,摇身一变成为切糕

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    typedef long long ll;
    const int N=1e5+5, M=1e6+5, INF=1e9;
    inline int read(){
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    
    int n, m, w, k, val[155][155], s, t;
    struct meow{int u, v;} a[205];
    
    namespace mf {
    	struct edge{int v, ne, c, f;} e[M];
    	int cnt=1, h[N];
    	inline void ins(int u, int v, int c) {
    		e[++cnt]=(edge){v, h[u], c, 0}; h[u]=cnt;
    		e[++cnt]=(edge){u, h[v], 0, 0}; h[v]=cnt;
    	}
    	
    	int q[N], head, tail, d[N], vis[N];
    	bool bfs() {
    		memset(vis, 0, sizeof(vis));
    		head=tail=1;
    		q[tail++]=s; vis[s]=1; d[s]=0;
    		while(head != tail) {
    			int u = q[head++];
    			for(int i=h[u];i;i=e[i].ne) 
    				if(!vis[e[i].v] && e[i].c > e[i].f) {
    					vis[e[i].v] = 1; d[e[i].v] = d[u]+1;
    					q[tail++] = e[i].v;
    					if(e[i].v == t) return true;
    				}
    		}
    		return false;
    	}
    	int cur[N];
    	int dfs(int u, int a) {
    		if(u==t || a==0) return a;
    		int flow=0, f;
    		for(int &i=cur[u];i;i=e[i].ne) 
    			if(d[e[i].v] == d[u]+1 && (f = dfs(e[i].v, min(a, e[i].c-e[i].f)) ) > 0) {
    				flow += f;
    				e[i].f += f;
    				e[i^1].f -= f;
    				a -= f;
    				if(a == 0) break;
    			}
    		if(a) d[u] = -1;
    		return flow;
    	}
    	int dinic() {
    		int flow=0;
    		while(bfs()) { 
    			for(int i=s; i<=t; i++) cur[i] = h[i];
    			flow += dfs(s, INF); 
    		}
    		return flow;
    	}
    
    	bool check(int d) {
    		s = 0; t = n*k + 1;
    		cnt=1; memset(h, 0, sizeof(h));
    		for(int i=1; i<=n; i++) {
    			ins(s, i, INF), ins(i + (k-1)*n, t, val[i][k]);
    			for(int j=1; j<k; j++) ins(i + (j-1)*n, i + j*n, val[i][j]);
    		}
    		for(int i=1; i<=m; i++) 
    			for(int j=1+d; j<=k; j++) {
    				ins(a[i].u + (j-1)*n, a[i].v + (j-d-1)*n, INF);
    				ins(a[i].v + (j-1)*n, a[i].u + (j-d-1)*n, INF);
    			}
    		return dinic() <= w;
    	}
    }
    
    void solve() {
    	int l=0, r=k, ans=-1;
    	while(l <= r) {
    		int mid = (l+r)>>1;
    		if(mf::check(mid)) ans = mid, r = mid-1;
    		else l = mid+1;
    	}
    	printf("%d", ans);
    }
    int main() {
    	//freopen("in", "r", stdin);
    	freopen("cdcq_c.in", "r", stdin);
    	freopen("cdcq_c.out", "w", stdout);
    	n=read(); m=read(); w=read(); k=read();
    	for(int i=1; i<=m; i++) a[i].u = read(), a[i].v = read();
    	for(int i=1; i<=n; i++) for(int j=1; j<=k; j++) val[i][j] = read();
    	solve();
    }
    
    
  • 相关阅读:
    python自动化测试(3)- 自动化框架及工具
    python自动化测试(2)-自动化基本技术原理
    软件开发过程自动化原理及技术(完整示例)
    网络验证码--你到底是爱它还是恨它?
    python的高性能web应用的开发与测试实验
    接口应用小玩具-博客园积分排名变动监控工具
    openwrt-智能路由器hack技术(2)---"网路信息监控和窃取"
    Java中的Date和时区转换
    fastjson JSONObject遍历
    【git】强制覆盖本地代码(与git远程仓库保持一致)
  • 原文地址:https://www.cnblogs.com/candy99/p/6704511.html
Copyright © 2011-2022 走看看