raiting 又掉了,明天早上爬起来继续搞,hehe
A题:好像用数组打标记的方法更简单,反正我直接套了两个树状数组。。。。
http://codeforces.com/contest/295/submission/3507289
B题:本场比赛的败笔,在更新最短路的时候姿势不够正确,然后交了几遍才过。。
做法就是倒着搞,如果更新了某点对的最短路,就要减去相应的差值。
http://codeforces.com/contest/295/submission/3511531
C题:搜索 + DP dp[a][b][c]表示这边有a个50公斤的人 b个100公斤的人,c为0表示在这边,为1表示在对岸 的且最快到达这个状态的达到最总方案数,因为要最快,所以是要bfs 过去
http://codeforces.com/contest/295/submission/3514654
D提
E题:赤裸裸的数据结构题。。。。。
先给你n个数,x1 x2 x3 x4 x5.....xn
然后有两种操作
1 a b 表示将 xa变成xb
2 l r
也就是所有的大的数减去小的数的和,且这些数都在l r区间里
开始一直在想通过加减操作得出答案,因为以前做过一个题是让你求一段区间内ai * i 的和,但是那个题不需要更新,所以想了一会就被我枪毙掉了。。。。
这道题显然要支持更新操作,那肿么办肿么办,这种线段树题肯定就是想怎么区间合并了。一首先要记录这么几个东西
ans sum cnt
sum是区间和,cnt是区间内有几个数 ans是这段区间的答案
现在考虑合并,其实很简单的,贴一段代码就懂了。。。。。
sum[rt] = sum[rt<<1] + sum[rt<<1|1]; ans[rt] = ans[rt<<1] + ans[rt<<1|1] - sum[rt<<1]*cnt[rt<<1|1] + sum[rt<<1|1]*cnt[rt<<1]; cnt[rt] = cnt[rt<<1] + cnt[rt<<1|1];
这道题关键还是要写好查询函数!!注意有些地方超int,我就是这样写傻了,查了半天
然后还有呢??好像也没了。
速度还是挺快的
#include <cstdio> #include <iostream> #include <vector> #include <algorithm> using namespace std; typedef long long lld; #define all(v) (v).begin(), (v).end() #define sqr(x) ((x)*(x)) #define REP(i,n) for(int i = 0; i < n ; i++) #define REV(s) reverse(s.begin(),s.end()) #define PB push_back #define MP make_pair const int maxn = 200010; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 int dir[4][2] = {1,0,0,1,-1,0,0,-1}; //~segment_tree vector<int> allx; struct Seg{ lld sum[maxn<<2]; lld ans[maxn<<2]; int cnt[maxn<<2]; void pushup(int rt) { sum[rt] = sum[rt<<1] + sum[rt<<1|1]; ans[rt] = ans[rt<<1] + ans[rt<<1|1] - sum[rt<<1]*cnt[rt<<1|1] + sum[rt<<1|1]*cnt[rt<<1]; cnt[rt] = cnt[rt<<1] + cnt[rt<<1|1]; } void build(int l,int r,int rt) { sum[rt] = 0; ans[rt] = 0; cnt[rt] = 0; if(l==r) return ; int m = l + r >> 1; build(lson); build(rson); } void update(int p,int v,int l,int r,int rt) { if(l==r){ sum[rt] += (lld)allx[p]*v ; cnt[rt] += v; ans[rt] = 0; return ; } int m = l + r>>1; if(p<=m) update(p,v,lson); else update(p,v,rson); pushup(rt); } pair<pair<lld,lld>,lld> query(int L,int R,int l,int r,int rt){ if(L <= l && r <= R) { return MP(MP(ans[rt],sum[rt]),cnt[rt]); } int m = l + r >>1; lld ret = 0, lsum = 0 , rsum = 0 , lcnt = 0, rcnt = 0; if(L <= m) { pair<pair<lld,lld>,lld> pl = query(L,R,lson); ret += pl.first.first; lsum += pl.first.second; lcnt += pl.second; } if(R > m) { pair<pair<lld,lld>,lld> pr = query(L,R,rson); ret += pr.first.first; rsum += pr.first.second; rcnt += pr.second; } return MP(MP(ret - lsum*rcnt + rsum*lcnt,lsum+rsum),lcnt+rcnt); } }seg; struct query { int t,l,r; }q[maxn]; int n , m , tot; int num[maxn]; int getid(int num) { return lower_bound(all(allx),num) - allx.begin(); } int p[maxn] , d[maxn]; int main() { int t , l ,r , a; scanf("%d",&n); vector<int> tx,cx; REP(i,n){ scanf("%d",&num[i]); allx.PB(num[i]); tx.PB(num[i]); } cx = tx; scanf("%d",&m); REP(i,m){ scanf("%d%d%d",&q[i].t,&q[i].l,&q[i].r); if(q[i].t==1){ int p = q[i].l , d = q[i].r; p--; tx[p] += d; allx.PB(tx[p]); } } tx=cx; sort(all(allx)); allx.erase(unique(all(allx)),allx.end()); tot = allx.size(); seg.build(0,tot,1); REP(i,n){ int id = getid(num[i]); seg.update(id,1,0,tot,1); } REP(i,m){ if(q[i].t == 1){ int p = q[i].l , d = q[i].r; p --; int val = tx[p]; tx[p] += d; int id1 = getid(val); int id2 = getid(tx[p]); seg.update(id1,-1,0,tot,1); seg.update(id2,1,0,tot,1); } else { int l = q[i].l , r = q[i].r; l = lower_bound(allx.begin(),allx.end(),q[i].l) - allx.begin(); r = upper_bound(allx.begin(),allx.end(),q[i].r) - allx.begin(); r--;if(l>r) {puts("0");continue;} pair<pair<lld,lld>,lld> ans = seg.query(l,r,0,tot,1); printf("%I64d\n",ans.first.first); } } return 0; }
作者:haha593572013 发表于2013-4-12 17:16:42 原文链接
阅读:26 评论:0 查看评论