#include <iostream> #include <stdio.h> #include <cstring> #include <vector> #include <utility> #include <algorithm> #include <cassert> using namespace std; #define int long long typedef long long LL; const int MAX_N = 1e4 +6; const int MAX_M = 1e4 +6; const int MAX_P = 18; struct Edge { int to; LL w; void _() { cout<<"to = "<<to<<" , w = "<<w<<endl; } }; Edge MP(int _to,LL _w) { return Edge{_to,_w}; } vector<Edge> edg[MAX_N]; struct Cen { int par; LL add; LL minus; int sz; void _() { cout<<"par = "<<par<<" , add = "<<add<<" , minus = "<<minus<<" , sz = "<<sz<<endl; } } cen[MAX_N]; int now[MAX_N]; int depth[MAX_N]; Edge lca[MAX_P][MAX_N]; bool visit[MAX_N]; int stamp; int tin[MAX_N],tout[MAX_N]; void dfs1(int id,int p,LL w,int cur_depth) { tin[id] = stamp++; visit[id] = 1; lca[0][id] = MP(p,w); depth[id] = cur_depth; for (auto i:edg[id]) { if (!visit[i.to]) { dfs1(i.to,id,i.w,cur_depth+1); } } tout[id] = stamp++; } vector<int> v; int sz[MAX_N]; int mx[MAX_N]; void dfs3(int id) { visit[id]=1; sz[id]=1; mx[id]=0; v.push_back(id); for (auto i:edg[id]) { if (!visit[i.to]) { dfs3(i.to); sz[id] += sz[i.to]; mx[id] = max(mx[id],sz[i.to]); } } } Cen MP4(int par,LL add,LL minus,int sz) { return Cen{par,add,minus,sz}; } void dfs2(int id,int par_cen) { v.clear(); dfs3(id); int can=-1; int tot=v.size(); for (auto i:v) { visit[i]=0; if (max(mx[i],tot-sz[i]) <= tot/2) { can = i; } } visit[can]=true; cen[can] = MP4(par_cen,0,0,0); for (auto i:edg[can]) { if (!visit[i.to]) { dfs2(i.to,can); } } } bool is_anc(int son,int parent) { return tin[son] >= tin[parent] && tout[son] <= tout[parent]; } LL get_dis(int x,int y) { if (depth[x] > depth[y]) swap(x,y); if (x==y) return 0; //x is lower if(is_anc(y,x)) { //we need only from y to x LL ret=0; for (int i=MAX_P-1;i>=0;i--) { if (!is_anc(x,lca[i][y].to)) { ret += lca[i][y].w; y = lca[i][y].to; } } ret += lca[0][y].w; return ret; } else { int tx=x,ty=y; x=tx,y=ty; LL ret=0; for (int i=MAX_P-1;i>=0;i--) { if (!is_anc(x,lca[i][y].to)) { ret += lca[i][y].w; y = lca[i][y].to; } } ret += lca[0][y].w; x=ty,y=tx; for (int i=MAX_P-1;i>=0;i--) { if (!is_anc(x,lca[i][y].to)) { ret += lca[i][y].w; y = lca[i][y].to; } } ret += lca[0][y].w; return ret; } } void add(int id) { int now=id; while (now != -1) { cen[now].add += get_dis(now,id); cen[now].sz++; if (cen[now].par == -1) break; cen[now].minus += get_dis(cen[now].par,id); now = cen[now].par; } } void deleted(int id) { int now=id; while (now != -1) { cen[now].add -= get_dis(now,id); cen[now].sz--; if (cen[now].par == -1) break; cen[now].minus -= get_dis(cen[now].par,id); now = cen[now].par; } } LL query(int id) { int now=id; LL ret=0; int totsz=0; while (now != -1) { ret += (cen[now].add - cen[now].minus); ret += (cen[now].sz - totsz)*get_dis(id,now); totsz = cen[now].sz; now = cen[now].par; } return ret; } main () { int T; scanf("%lld",&T); while (T--) { int n,m,q; scanf("%lld %lld %lld",&n,&m,&q); for (int i=0;n>=i;i++) { edg[i].clear(); } for (int i=1;n>i;i++) { int a,b,c; scanf("%lld %lld %lld",&a,&b,&c); edg[a].push_back(MP(b,c)); edg[b].push_back(MP(a,c)); } stamp=0; memset(visit,0,sizeof(visit)); dfs1(1,1,0,1); for (int i=1;MAX_P>i;i++) { for (int j=1;n>=j;j++) { lca[i][j] = MP(lca[i-1][lca[i-1][j].to].to,lca[i-1][j].w+lca[i-1][lca[i-1][j].to].w); } } memset(visit,0,sizeof(visit)); dfs2(1,-1); now[1]=1; for (int i=2;m>=i;i++) { add(1); now[i]=1; } while (q--) { int a,b; scanf("%lld %lld",&a,&b); if (a==1) { now[a]=b; } else { deleted(now[a]); now[a]=b; add(now[a]); } LL ret=query(now[1]); printf("%lld\n",ret); assert(ret>=0); } } }
2017年4月18日 星期二
(IOICamp_Judge) 導遊讚哥讚! [重心剖分]
https://judge.ioicamp.org/problems/78
(TIOJ) 1903 . 【Gate】這個笑容由我來守護 - EXTREME [可刪邊並查集] [時間線段樹] [unodered_map]
http://tioj.ck.tp.edu.tw/problems/1903
((解釋有空再補))
((解釋有空再補))
#include <iostream> #include <stdio.h> #include <utility> #include <map> #include <set> #include <vector> #include <cassert> #include <unordered_map> using namespace std; typedef long long LL; typedef pair<int,int> pii; const LL MAX_N = 5e5 + 6; namespace std { template <> struct hash<pii> { LL operator()(const pii &p) const { return p.first*MAX_N+p.second; } }; } struct Node { static Node mem[4*MAX_N]; Node *lc,*rc; vector<pii> v; Node() { lc=rc=NULL; v.clear(); } } Node::mem[4*MAX_N],*ptr=Node::mem; Node* Build(int L,int R) { Node* node=new(ptr++)Node(); if (L==R) { return node; } int mid=(L+R)>>1; node->lc=Build(L,mid); node->rc=Build(mid+1,R); return node; } void modify(Node* node,int L,int R,int l,int r,pii edge) { if (L>r || l>R) return; else if (l<=L && R<=r) { node->v.push_back(edge); return; } int mid=(L+R)>>1; modify(node->lc,L,mid,l,r,edge); modify(node->rc,mid+1,R,l,r,edge); } int ans[MAX_N]; struct Event { int tx,ty; int ori_sz_tx,ori_sz_ty; int ori_p_tx,ori_p_ty; pii range; void gao(int _tx,int _ty,int _ori_sz_tx,int _ori_sz_ty,int _ori_p_tx,int _ori_p_ty,pii _range) { tx=_tx; ty=_ty; ori_sz_tx=_ori_sz_tx; ori_sz_ty=_ori_sz_ty; ori_p_tx=_ori_p_tx; ori_p_ty=_ori_p_ty; range=_range; } }; vector<Event> ee; struct DisjointSet { int p[MAX_N]; int sz[MAX_N]; int ans; void init(int n) { ans=n; for (int i=0;n>=i;i++) { p[i] = i; sz[i]=1; } } int Find(int x) { return p[x]==x?x:Find(p[x]); } void Union(int x,int y,pii range) { int tx=Find(x); int ty=Find(y); if (tx == ty) { return; } if (sz[tx] < sz[ty]) swap(tx,ty); assert(sz[tx]>=sz[ty]); Event e; e.gao(tx,ty,sz[tx],sz[ty],p[tx],p[ty],range); ee.push_back(e); sz[tx] += sz[ty]; p[ty] = p[tx]; ans--; } void recover(Event e) { p[e.tx] = e.ori_p_tx; p[e.ty] = e.ori_p_ty; sz[e.tx] = e.ori_sz_tx; sz[e.ty] = e.ori_sz_ty; ans++; } } djs; void visit(Node* node,int L,int R) { //deal with the edges pii range=make_pair(L,R); for (pii i:node->v) { djs.Union(i.first,i.second,range); } if (L==R) { ans[L] = djs.ans; } else { int mid=(L+R)>>1; visit(node->lc,L,mid); visit(node->rc,mid+1,R); } while (!ee.empty() && ee.back().range == range) { djs.recover(ee.back()); ee.pop_back(); } } LL hash(pii i) { return i.first*MAX_N+i.second; } int main () { int T; scanf("%d",&T); while (T--) { ptr=Node::mem; int n,m,q; scanf("%d %d %d",&n,&m,&q); djs.init(n); Node* root=Build(1,q+1); unordered_map<pii,pii> mp; //start,count for (int i=1;m>=i;i++) { int a,b; scanf("%d %d",&a,&b); if (a>b) swap(a,b); pii edge=make_pair(a,b); pii ret=mp[edge]; if (ret == make_pair(0,0)) ret=make_pair(1,1); else ret.second++; mp[edge]=ret; } int nn=q+1; for (int i=2;q+1>=i;i++) { getchar(); char c; int a,b; scanf("%c %d %d",&c,&a,&b); if (a>b) swap(a,b); pii edge=make_pair(a,b); if (c=='N') { pii ret=mp[edge]; if (ret == make_pair(0,0)) mp[edge] = make_pair(i,1); else { ret.second++; mp[edge]=ret; } } else if (c=='D') { pii ret=mp[edge]; ret.second--; if (ret.second==0) { modify(root,1,nn,ret.first,i-1,edge); ret=make_pair(0,0); } mp[edge]=ret; } } for (auto p:mp) { pii edge=p.first; pii st=p.second; if (st.second==0) continue; modify(root,1,nn,st.first,q+1,edge); } visit(root,1,nn); for (int i=2;nn>=i;i++) { printf("%d\n",ans[i]); } } }
(Zerojudge) b412: 【記憶中】之記憶中的并查集 [可持久化並查集]
https://zerojudge.tw/ShowProblem?problemid=b412
使用黑魔法rope XD
其實可用可持久化線段樹
有啟發式合併 + 路徑壓縮XD
使用黑魔法rope XD
其實可用可持久化線段樹
有啟發式合併 + 路徑壓縮XD
#include <iostream> #include <stdio.h> #include <ext/rope> using namespace std; using namespace __gnu_cxx; const int MAX_N = 1e5 + 6; rope<int> *p[MAX_N],*sz[MAX_N]; int pp[MAX_N],szz[MAX_N]; int Find(int ver,int x) { int ret; if (p[ver]->at(x) == x) return x; ret = Find(ver,p[ver]->at(x)); if (p[ver]->at(x) == ret) return ret; p[ver]->replace(x,ret); return ret; } void Union(int ver,int x,int y) { x = Find(ver,x); y = Find(ver,y); if (x==y) return; if (sz[ver]->at(x) > sz[ver]->at(y)) { sz[ver]->replace(x,(sz[ver]->at(x) + sz[ver]->at(y))); p[ver]->replace(y,x); } else { sz[ver]->replace(y,(sz[ver]->at(x) + sz[ver]->at(y))); p[ver]->replace(x,y); } } int main () { int n,m; scanf("%d %d",&n,&m); int ans=0; for (int i=0;n>=i;i++) { pp[i] = i; szz[i] = 1; } n+=3; p[0] = new rope<int>(pp,pp+n+1); sz[0]= new rope<int>(szz,szz+n+1); for (int i=1;m>=i;i++) { int a; scanf("%d",&a); a^=ans; if (a==0) { //go to history version int b; scanf("%d",&b); b^=ans; p[i] = p[b]; sz[i]=sz[b]; } else if (a==1) { int b,c; scanf("%d %d",&b,&c); p[i] = new rope<int>(*p[i-1]); sz[i]= new rope<int>(*sz[i-1]); b^=ans; c^=ans; Union(i,b,c); } else { int b,c; scanf("%d %d",&b,&c); p[i] = new rope<int>(*p[i-1]); sz[i]= new rope<int>(*sz[i-1]); b^=ans; c^=ans; ans = (Find(i,b) == Find(i,c)); printf("%d\n",ans); } } }
(Zerojudge) d539: 區間 MAX [終極sparse-table]
https://zerojudge.tw/ShowProblem?problemid=d539
花O(n lg lg n)預處理,花O(1)查詢任意區間的RMQ。
想法:
把lgN東西分成一塊,對每一塊做Sparse-Table,
總複雜度為O( N/(lgN) * lgN * lg(lgN) ) = O(N lg lg N)
再對每一塊的Max做Sparse-Table : O( (N/lgN) * lg(N/lg(N)) ) = O(N)
之後就可以O(1)查詢。想想看吧!
花O(n lg lg n)預處理,花O(1)查詢任意區間的RMQ。
想法:
把lgN東西分成一塊,對每一塊做Sparse-Table,
總複雜度為O( N/(lgN) * lgN * lg(lgN) ) = O(N lg lg N)
再對每一塊的Max做Sparse-Table : O( (N/lgN) * lg(N/lg(N)) ) = O(N)
之後就可以O(1)查詢。想想看吧!
//use sparse table + magic to <O(n lg lg n),O(1)> #include <iostream> #include <stdio.h> #include <cmath> using namespace std; const int MAX_N = 5e5 +60; const int MAX_P = 22; const int MAX_NN = 19; //lg N const int MAX_MM = 5; const int MAX_NNN = 30000+6; const int MAX_MMM = 16; //lg NN const int _INF = -2147483648; int a[MAX_N]; int st_small[MAX_NNN][MAX_MM][MAX_NN]; int st_big[MAX_MMM][MAX_NNN]; int lg2[MAX_N]; int pow2[MAX_P]; void make_st_small(int n,int *a,int st[MAX_MM][MAX_NN]) { for (int i=0;n>i;i++) { st[0][i] = a[i]; } for (int i=1;MAX_MM>i;i++) { for (int j=0;n>j;j++) { int r=j+pow2[i-1]; if (r>=n) r=n-1; st[i][j] = max(st[i-1][j],st[i-1][r]); } } } int query_small(int st[MAX_MM][MAX_NN],int l,int r) { int dis=(r-l+1); return max(st[lg2[dis]][l],st[lg2[dis]][r-pow2[lg2[dis]]+1]); } void make_st_big(int n,int *a,int st[MAX_MMM][MAX_NNN]) { for (int i=0;n>i;i++) { st[0][i] = a[i]; } for (int i=1;MAX_MMM>i;i++) { for (int j=0;n>j;j++) { int r=j+pow2[i-1]; if (r>=n) r=n-1; st[i][j] = max(st[i-1][j],st[i-1][r]); } } } int query_big(int st[MAX_MMM][MAX_NNN],int l,int r) { int dis=(r-l+1); return max(st[lg2[dis]][l],st[lg2[dis]][r-pow2[lg2[dis]]+1]); } void init() { pow2[0]=1; for (int i=1;MAX_P>i;i++) { pow2[i] = pow2[i-1]*2; } lg2[1] = 0; int id=1; for (int i=2;MAX_N>i;i++) { if (i==pow2[id]) { lg2[i] = lg2[i-1]+1; id++; } else { lg2[i] = lg2[i-1]; } } } int tmp[MAX_NN]; int aa[MAX_NNN]; int main () { init(); int n; scanf("%d",&n); for (int i=0;n>i;i++) { scanf("%d",&a[i]); } int small_sz=lg2[n]; if (small_sz<2) small_sz=2; int totgroup=n/small_sz + !(n%small_sz==0); for (int i=0;totgroup>i;i++) { int t=0; for (int j=i*small_sz;i*small_sz+small_sz>j;j++) { if (j<n) tmp[t++] = a[j]; else tmp[t++] = _INF; } make_st_small(small_sz,tmp,st_small[i]); aa[i] = query_small(st_small[i],0,small_sz-1); } make_st_big(totgroup,aa,st_big); int q; scanf("%d",&q); while (q--) { int l,r; scanf("%d %d",&l,&r); if (l>r) swap(l,r); l--; r--; if (l/small_sz == r/small_sz) { //in the same group int group_first=(l/small_sz)*small_sz; printf("%d\n",query_small(st_small[l/small_sz],l-group_first,r-group_first)); continue; } int ans=max(query_small(st_small[l/small_sz],l-(l/small_sz)*small_sz,small_sz-1), query_small(st_small[r/small_sz],0,r-(r/small_sz)*small_sz)); if (l/small_sz +1 == r/small_sz) printf("%d\n",ans); else printf("%d\n",max(ans,query_big(st_big,l/small_sz+1,r/small_sz-1))); } }
(Zerojudge) d779: NOIP2009 3.最优贸易
https://zerojudge.tw/ShowProblem?problemid=d779
我是先想50%,之後才想到100%的!
在寫50%的時候,我發現圖是一個DAG,用DAG來維護一些東西。
那在推廣到100%的時候,我就在想,要怎麼把整張圖推廣到DAG --> SCC!
50%的版本:
100%的版本:
我是先想50%,之後才想到100%的!
在寫50%的時候,我發現圖是一個DAG,用DAG來維護一些東西。
那在推廣到100%的時候,我就在想,要怎麼把整張圖推廣到DAG --> SCC!
50%的版本:
#include <iostream> #include <stdio.h> #include <vector> #include <cstring> #include <queue> using namespace std; const int MAX_N = 1e5 +6; vector<int> edg[MAX_N]; int a[MAX_N]; int mn[MAX_N]; int mxans[MAX_N]; int deg[MAX_N]; int main () { int n,m; scanf("%d %d",&n,&m); for (int i=1;n>=i;i++) { scanf("%d",&a[i]); mn[i] = a[i]; mxans[i]=0; } for (int i=0;m>i;i++) { int a,b,c; scanf("%d %d %d",&a,&b,&c); if (c==1) edg[a].push_back(b); else { edg[a].push_back(b); edg[b].push_back(a); } deg[b]++; } int ans=0; queue<int> que; que.push(1); while (!que.empty()) { int t=que.front(); que.pop(); mxans[t] = max(mxans[t],a[t]-mn[t]); for (int i:edg[t]) { mn[i] = min(mn[i],mn[t]); deg[i]--; mxans[i] = max(mxans[i],mxans[t]); if (deg[i]==0) que.push(i); } } printf("%d\n",mxans[n]); }
100%的版本:
#include <iostream> #include <stdio.h> #include <cstring> #include <vector> #include <algorithm> #include <queue> using namespace std; const int MAX_N = 1e5 + 6; const int INF = 1e9 + 7; vector<int> edg[MAX_N]; vector<int> rev_edg[MAX_N]; vector<int> scc_edg[MAX_N]; int scc_mx[MAX_N],scc_mn[MAX_N],scc_ans[MAX_N]; int a[MAX_N]; bool visit[MAX_N]; int get_stamp[MAX_N]; int in_scc[MAX_N]; int ansmx[MAX_N]; int deg[MAX_N]; void gao1(int id,int &stamp) { visit[id]=1; for (int i:rev_edg[id]) { if (!visit[i]) { gao1(i,stamp); } } get_stamp[stamp++]=id; } void gao2(int id,int scc) { visit[id]=1; for (int i:edg[id]) { if (!visit[i]) { gao2(i,scc); } } in_scc[id]=scc; scc_mx[scc] = max(scc_mx[scc],a[id]); scc_mn[scc] = min(scc_mn[scc],a[id]); } int build_scc(int n) { memset(visit,0,sizeof(visit)); int stamp=1; for (int i=1;n>=i;i++) { if (!visit[i]) { gao1(i,stamp); } } fill(scc_mx,scc_mx+MAX_N,-INF); fill(scc_mn,scc_mn+MAX_N,INF); memset(visit,0,sizeof(visit)); int scc=0; for (int i=n;i>=1;i--) { if (!visit[get_stamp[i]]) { gao2(get_stamp[i],++scc); } } for (int i=1;n>=i;i++) { for (int j:edg[i]) { if (in_scc[i] != in_scc[j]) { // cout<<"build edge i = "<<in_scc[i]<<" , j = "<<in_scc[j]<<endl; scc_edg[in_scc[i]].push_back(in_scc[j]); } } } return scc; } int main () { int n,m; scanf("%d %d",&n,&m); for (int i=1;n>=i;i++) { scanf("%d",&a[i]); } for (int i=1;m>=i;i++) { int a,b,c; scanf("%d %d %d",&a,&b,&c); edg[a].push_back(b); rev_edg[b].push_back(a); if (c==2) { edg[b].push_back(a); rev_edg[a].push_back(b); } } int scc=build_scc(n); // cout<<"scc = "<<scc<<endl; // for (int i=1;n>=i;i++) { // cout<<"in_scc["<<i<<"] = "<<in_scc[i]<<endl; // } queue<int> que; for (int i=1;scc>=i;i++) { for (int j:scc_edg[i]) { deg[j]++; } } que.push(in_scc[1]); while (!que.empty()) { int t=que.front(); // cout<<"T = "<<t<<endl; que.pop(); ansmx[t] = max(ansmx[t],scc_mx[t]-scc_mn[t]); for (int i:scc_edg[t]) { deg[i]--; scc_mn[i] = min(scc_mn[i],scc_mn[t]); ansmx[i] = max(ansmx[i],ansmx[t]); if (deg[i] == 0) que.push(i); } } printf("%d\n",ansmx[in_scc[n]]); }
2017年4月12日 星期三
(SPOJ) RPLN - Negative Score [Sparse-Table]
http://www.spoj.com/problems/RPLN/
implement with sparse table
<O(n lg n), O(1)>
implement with sparse table
<O(n lg n), O(1)>
//use sparse table #include <iostream> #include <stdio.h> using namespace std; const int MAX_N = 1e5 +6; const int MAX_P = 18; int a[MAX_N]; int st[MAX_P][MAX_N]; int lg2[MAX_N]; int pow2[MAX_P]; int main () { pow2[0]=1; for (int i=1;MAX_P>i;i++) { pow2[i] = pow2[i-1]*2; } lg2[1] = 0; int id=1; for (int i=2;MAX_N>i;i++) { if (i==pow2[id]) { lg2[i] = lg2[i-1]+1; id++; } else { lg2[i] = lg2[i-1]; } } int T; scanf("%d",&T); int cases=0; while (T--) { int n,q; scanf("%d %d",&n,&q); for (int i=1;n>=i;i++) { scanf("%d",&a[i]); st[0][i] = a[i]; } for (int i=1;MAX_P>i;i++) { for (int j=1;n>=j;j++) { int r=j+pow2[i-1]; if (r>n) r=n; st[i][j] = min(st[i-1][j],st[i-1][r]); } } printf("Scenario #%d:\n",++cases); while (q--) { int l,r; scanf("%d %d",&l,&r); int dis=(r-l+1); printf("%d\n",min(st[lg2[dis]][l],st[lg2[dis]][r-pow2[lg2[dis]]+1])); } } }
2017年4月7日 星期五
(UVA) 1106 - Machine Works [CDQ分治] [DP斜率優化]
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=24&page=show_problem&problem=3547
#include <iostream> #include <stdio.h> #include <cstring> #include <algorithm> #include <vector> using namespace std; //dp[i] = max(dp[j] + r[j] - p[j] + (t[i] - t[j] - 1)*g[j]) typedef long long LL; typedef __int128 LLL; const int MAX_N = 1e5 + 6; struct Mac { LL t,p,r,g; void input() { scanf("%lld %lld %lld %lld",&t,&p,&r,&g); } } mac[MAX_N]; struct Line { LLL m,b; Line(LL _m,LL _b) { m=_m; b=_b; } LLL val(LLL x) { return m*x+b; } }; bool operator<(const Mac &m1,const Mac &m2) { return m1.t < m2.t; } bool operator<(const Line &l1,const Line &l2) { return l1.m < l2.m || l1.m==l2.m && l1.b<l2.b; } LL dp[MAX_N]; //dp[i] = max(dp[j] + r[j] - p[j] + (t[i] - t[j] + 1)*g[j]) bool check(Line _0,Line _1,Line _2) { return (_0.m-_2.m)*(_0.b-_1.b) > (_0.b-_2.b)*(_0.m-_1.m); } void do_things(int L,int R) { int mid=(L+R)>>1; vector<Line> v; for (int j=L;mid>=j;j++) { if (dp[j] >= mac[j].p) { v.push_back(Line(mac[j].g,dp[j]+mac[j].r-mac[j].p+(-mac[j].t-1)*mac[j].g)); } } sort(v.begin(),v.end()); vector<Line> dq; //use vector as deque XD for (Line l:v) { while (dq.size() && dq[dq.size()-1].m == l.m) dq.pop_back(); while (dq.size()>1 && check(l,dq[dq.size()-1],dq[dq.size()-2])) dq.pop_back(); dq.push_back(l); } if (!dq.size()) return; int now=0; for (int i=mid+1;R>=i;i++) { while (now+1<dq.size() && dq[now].val(mac[i].t) < dq[now+1].val(mac[i].t)) now++; dp[i] = max(LLL(dp[i]),dq[now].val(mac[i].t)); } } void cdq(int L,int R) { if (L==R) return; int mid=(L+R)>>1; cdq(L,mid); do_things(L,R); cdq(mid+1,R); } int main () { int n,c,d; int cases=0; while (scanf("%d %d %d",&n,&c,&d) != EOF) { if (!n && !c && !d) break; printf("Case %d: ",++cases); for (int i=1;n>=i;i++) { mac[i].input(); } memset(dp,0,sizeof(dp)); mac[0]=Mac{0,0,c,0}; mac[n+1]=Mac{d+1,0,0,0}; sort(mac,mac+(n+2)); cdq(0,n+1); printf("%lld\n",dp[n+1]); } }
訂閱:
文章 (Atom)