2012长春网络赛
2012-09-08 18:27
387 查看
acmicpc 解题报告汇总:http://acmicpc.info/archives/823
1:
线段树
(i-a)%k = 0 即i%k=a%k
节点维护一个二维数组add, add[a][b]=c,表示该区间下标i%a=b的加c
那么, update(l, r, k, l%k, v)这样就可以分到子区间了
但是, 这样会爆内存,因为a%b<b,可以节省一半, 这样就过了..
2:
先按第一维排序,然后第二维
然后对a的每个i,找出小于a[i].h的b.h,将对应的w塞到集合里
刚才已经保证了第一维满足了
然后贪心的从集合里面找a[i]能覆盖的最大的w
8:
dfs求出每个点的取值范围, 如果出现up<down的, 则矛盾...
11:
暴力, 3^15,
敲代码的时候两个set轮换...
卡过去了...
1:
线段树
(i-a)%k = 0 即i%k=a%k
节点维护一个二维数组add, add[a][b]=c,表示该区间下标i%a=b的加c
那么, update(l, r, k, l%k, v)这样就可以分到子区间了
但是, 这样会爆内存,因为a%b<b,可以节省一半, 这样就过了..
#pragma warning (disable: 4786) #include "stdio.h" #include "string.h" #include "iostream" #include "algorithm" #include "vector" #include "map" #include "set" using namespace std; const int N = 50005; int seg[N*3][55], da ; void update(int l, int r, int a, int b, int c, int rt, int L, int R) { if(l <= L && R <= r) { int i, ii = b; for(i = 1; i < a; ++i) { ii += i; } seg[rt][ii] += c; return; } int mid = (L+R)>>1; if(l <= mid) { update(l, r, a, b, c, rt<<1, L, mid); } if(r > mid) { update(l, r, a, b, c, rt<<1|1, mid+1, R); } } int query(int x, int rt, int L, int R) { int mid = (L+R)>>1, res = 0, i, j, ii; for(i = 1; i <= 10; ++i) { ii = x%i; for(j = 1; j < i; ++j) { ii += j; } res += seg[rt][ii]; } if(x <= L && R <= x) { return res; } if(x <= mid) { res += query(x, rt<<1, L, mid); } if(x > mid) { res += query(x, rt<<1|1, mid+1, R); } return res; } int main() { int n, q, i; while(~scanf("%d", &n)) { for(i = 1; i <= n; ++i) { scanf("%d", &da[i]); } memset(seg, 0, sizeof(seg)); scanf("%d", &q); int t, l, r, k, v; while(q--) { scanf("%d", &t); if(t==1) { scanf("%d%d%d%d", &l, &r, &k, &v); update(l, r, k, l%k, v, 1, 1, n); } else if(t==2) { scanf("%d", &i); printf("%d\n", da[i]+query(i, 1, 1, n)); } } } return 0; }
2:
先按第一维排序,然后第二维
然后对a的每个i,找出小于a[i].h的b.h,将对应的w塞到集合里
刚才已经保证了第一维满足了
然后贪心的从集合里面找a[i]能覆盖的最大的w
#pragma warning (disable: 4786) #include "stdio.h" #include "string.h" #include "iostream" #include "algorithm" #include "vector" #include "map" #include "set" using namespace std; typedef pair<int,int> PII; vector<PII> a, b; multiset<int> c; multiset<int>::iterator it; int main() { int t, n, h, w, i, j; scanf("%d", &t); while(t--) { scanf("%d", &n); a.clear(); b.clear(); for(i = 0; i < n; ++i) { scanf("%d%d", &h, &w); a.push_back(make_pair(h, w)); } for(i = 0; i < n; ++i) { scanf("%d%d", &h, &w); b.push_back(make_pair(h, w)); } sort(a.begin(), a.end()); sort(b.begin(), b.end()); int ans = 0; c.clear(); for(i=j=0; i<a.size(); ++i) { while(j<b.size() && b[j].first<=a[i].first) { c.insert(b[j].second); ++j; } it = c.upper_bound(a[i].second); if(it != c.begin() && !c.empty()) { --it; c.erase(it); ++ans; } } printf("%d\n", ans); } return 0; }
8:
dfs求出每个点的取值范围, 如果出现up<down的, 则矛盾...
#pragma warning (disable: 4786) #include "cstdio" #include "cstring" #include "cassert" #include "iostream" #include "algorithm" #include "vector" #include "map" #include "set" using namespace std; typedef __int64 ll; typedef pair<ll, ll> PII; typedef vector<int> VI; #define max(a, b) a>b?a:b #define min(a, b) a<b?a:b const int N = 11111; const ll inf = 0x7fffffffffffffff; VI mat ; PII seg ; int ok; void calc(int i, ll d, ll u) { ll nd = max(d, seg[i].first), nu = min(u, seg[i].second); if(nu < nd) { ok = 0; } seg[i].first = nd; seg[i].second = nu; } void dfs(int rt) { if(!ok || mat[rt].size() == 0) { return; } int i; ll dw = 1, up = inf; for(i = 0; i < mat[rt].size(); ++i) { dfs(mat[rt][i]); dw += seg[mat[rt][i]].first; } calc(rt, dw, up); } int main() { char c; int n, m, f, a, b, i; ll dw, up; while(~scanf("%d", &n)) { for(i = 1; i <= n; ++i) { seg[i].first = 1; seg[i].second = inf; mat[i].clear(); } for(i = 2; i <= n; ++i) { scanf("%d", &f); mat[f].push_back(i); } ok = 1; scanf("%d", &m); while(m--) { scanf("%d %c %d", &a, &c, &b); dw = 1; up = inf; if(c=='=') { dw = up = b; } else if(c=='<') { up = b-1; } else if(c=='>') { dw = b+1; } else { assert(0>1); } calc(a, dw, up); } dfs(1); puts(ok?"True":"Lie"); } return 0; }
11:
暴力, 3^15,
敲代码的时候两个set轮换...
卡过去了...
#pragma warning (disable: 4786) #include "stdio.h" #include "string.h" #include "iostream" #include "algorithm" #include "vector" #include "map" #include "set" using namespace std; struct node{ int a, b, c; node() { a=b=c=0; } node(int aa, int bb, int cc):a(aa), b(bb), c(cc){} bool operator < (const node & tmp) const { if(a!=tmp.a) { return a<tmp.a; } else if(b!=tmp.b) { return b<tmp.b; } else { return c<tmp.c; } } bool operator == (const node & tmp) const { return (a==tmp.a && b==tmp.b && c==tmp.c); } node operator + (const node & tmp) const { int aa=a+tmp.a, bb=b+tmp.b, cc=c+tmp.c; if(aa>bb) { swap(aa, bb); } if(aa>cc) { swap(aa, cc); } if(bb>cc) { swap(bb, cc); } return node(aa, bb, cc); } }; int isok(const node& n) { return (n.a+n.b>n.c); } vector<int> v; set<node> s[2]; int main() { int t, n, x, i; scanf("%d", &t); while(t--) { scanf("%d", &n); v.clear(); for(i=0; i<n; ++i) { scanf("%d", &x); v.push_back(x); } s[0].clear(); s[0].insert(node()); int a=0, b=1; set<node>::iterator it; for(i=0; i<n; ++i) { s[b].clear(); for(it=s[a].begin(); it!=s[a].end(); ++it) { s[b].insert(*it+node(v[i], 0, 0)); s[b].insert(*it+node(0, v[i], 0)); s[b].insert(*it+node(0, 0, v[i])); } swap(a, b); } int ans = 0; for(it=s[a].begin(); it!=s[a].end(); ++it) { if(isok(*it)) { ++ans; } } printf("%d\n", ans); } return 0; }
相关文章推荐
- 长春赛区2012 Alice and Bob 1002题 (网络赛)
- 长春网络赛2012 ACM/ICPC Asia Regional Changchun Online LianLianKan
- hdu 4272 2012长春赛区网络赛 dfs暴力 ***
- hdu 4273 2012长春赛区网络赛 三维凸包中心到最近面距离 ***
- 2012长春网络赛
- 2012长春网络赛赛后【完结】
- 2012 ACM/ICPC 长春赛区网络赛
- hdu 4274 Spy's Work(2012 长春网络赛 树形DP)
- 2012长春网络赛(hdu4267 hdu4268 hdu4274 hdu4276 hdu4277)
- 2012长春赛区网络赛总结
- 2012 ACM ICPC 长春网络赛B Alice And Bob 线段树的延伸利用
- hdu 4277 USACO ORZ(2012 ACM/ICPC Asia Regional Changchun Online 长春网络赛)
- hdu 4277 2012长春赛区网络赛 dfs+hashmap ***
- 长春赛区2012 A Simple Problem with Integers 1001题 (网络赛)
- HDU4267(2012长春网络赛)
- HDU 4268 树状数组 2012长春网络赛
- hdu 4274 2012长春赛区网络赛 树形dp ***
- 2012长春网络赛 B题(贪心+multiset处理二维问题)
- hdu 4274 Spy's Work (2012 长春网络赛)
- 长春赛区2012 USACO ORZ 1011题 (网络赛)