日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

2012网赛杭州赛区

發(fā)布時間:2024/3/24 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 2012网赛杭州赛区 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

1002 arrest

有k個警察在0點按順序遍歷1到n去抓小偷, 這樣構(gòu)圖時就要對編號小的連向編號大的, 之前要floyd處理。

我賽后的構(gòu)圖:對每個點的遍歷有個限制是必須是1次, 由于是費用流, 可以用將該流置為-inf的方法,強制改變訪問一次。

當(dāng)時比賽時zzc的構(gòu)圖:跑k次網(wǎng)絡(luò)流, 分別枚舉1~k個警察情況下的最小費用, 也同樣用了一個-inf的方法, 不過是加到了城市之間的連通邊上,這樣就麻煩了一些。


我的代碼: source:0 , 0:1,? 0'(sink):2*n+2,? i:i<<1, i' : 1<<1|1

addedge(0, 1, K, 0);for (int i=1; i<=n; ++i)addedge(1, i<<1, 1, dist[0][i]), addedge(i<<1, i<<1|1, 1, ness);for (int i=1; i<=n; ++i)for(int j=i+1; j<=n; ++j)addedge(i<<1|1, j<<1, 1, dist[i][j]); for (int i=1; i<=n; ++i)addedge(i<<1|1, 2*n+2, 1, dist[i][0]);addedge(1, 2*n+2, K, 0);int ans=mcmf(0, 2*n+2)-n*ness;

zzc代碼:

for(int kk = 1; kk <= K; ++kk){// S->0, 0->1, 1->2, 1'->3, 0'(T), 2n+2g.build(2 * n + 3);g.addedge(0, 1, kk, 0);for(int i = 1; i <= n; ++i)g.addedge(2 * i, 2 * i + 1, 1, 0);for(int i = 1; i <= n; ++i){g.addedge(1, 2 * i, 1, dist[0][i]);g.addedge(2 * i + 1, 2 * n + 2, 1, dist[i][0]);}for(int i = 1; i <= n; ++i){for(int j = i + 1; j <= n; ++j){g.addedge(2 * i + 1, 2 * j, 1, dist[i][j] - inf);}}int ret = g.mincost(0, 2 * n + 2);ret += (n - kk) * inf;ans = std::min(ans, ret);}


1008 樹狀數(shù)組+離線+離散化也可以二分+劃分樹, 總之是道水題

using namespace std; ///*** for STL ***/// #define fst first #define scd second #define pb push_back #define mp makepair #define lb lower_bound #define ub upper_bound const int maxn=100000+123; #define lowbit(x) ((x)&(-(x)))int C[2*maxn]; int N; int Query(int x){for (int res=0; ; res+=C[x], x-=lowbit(x))if(x==0)return res; } void Update(int x, int v){for (;x<=N; x+=lowbit(x))C[x]+=v; } void IUpdate(int s, int t, int v){Update(t+1, -v); Update(s, v); }int a[maxn], X[maxn], value[maxn]; vector<int > L[maxn], R[maxn];int ans[maxn]; int main() {int T; scanf("%d", &T);for(int I=1; I<=T; ++I){int n, m; scanf("%d%d", &n, &m);for (int i=0; i<n; ++i){scanf("%d", a+i);L[i].clear();R[i].clear();}for (int i=0; i<m; ++i){int aa, b, c; scanf("%d%d%d", &aa, &b, &c);L[aa].pb(i);R[b].pb(i);X[i]=value[i]=c;}memset (C, 0, sizeof(C));memset (ans, 0, sizeof(ans));sort(X, X+n);int xcnt=unique(X, X+n)-X;///printf("%d\n", xcnt);N=xcnt+1;for (int i=0; i<n; ++i){for (int j=0; j<L[i].size(); ++j){int id=L[i][j];int p=lower_bound(X, X+xcnt, value[id])-X+1;//printf("l==%d id==%d\n", p, id);ans[id]=Query(p);}int pp=lower_bound(X, X+xcnt, a[i])-X+1;IUpdate(pp, N, 1);for (int j=0; j<R[i].size(); ++j){int id=R[i][j];int p=lower_bound(X, X+xcnt,value[id])-X+1;//..printf("p==%d id=%d r==%d, l==%d\n", p, id, Query(p), ans[id]);ans[id]=Query(p)-ans[id];}}///printf("n===%d\n", n);printf("Case %d:\n", I);for (int i=0; i<m; ++i)printf("%d\n", ans[i]);}return 0; }


1010? hdu 4419 Colourful Rectangle (堆式線段樹)

比賽的時候很輕易想到了用3棵樹維護染色區(qū)間, 7個樹維護每種顏色的覆蓋長度, 每次更新時根據(jù)當(dāng)前點的被覆蓋狀態(tài)去更新長度, 但很快發(fā)現(xiàn)問了, 矩形面積并的算法cover的增減區(qū)間是對稱的所以不需要下傳標記, 但是后來發(fā)現(xiàn)不僅是不需要,而且是不能下傳標記, 如果標記信息下傳,比如+1的信息下傳后, 下次來的對稱區(qū)間的-1信息不會及時傳到原來的區(qū)間被下傳的區(qū)間,就會發(fā)生更新顏色的區(qū)間的判斷錯誤, 但是如果不下傳又沒法處理交叉染色的區(qū)間的實際顏色(會被在線段樹上方的顏色覆蓋),這就悲劇de卡了3小時(其實還是源于對掃描線的不正確理解)。

賽后想了2天還是沒解決標記下傳的問題。

后來還是看了別人的代碼, 和我一個思路的建樹的人, 他們也沒有標記下傳而是對區(qū)間更新時直接做了特殊的轉(zhuǎn)移, 對于當(dāng)前點的狀態(tài)state,如果是0, 則將當(dāng)前點的狀態(tài)更新為2個兒子狀態(tài)的和, 如果不是, 則找出兒子區(qū)間里各顏色i(1<=i<=7)的長度, 將當(dāng)前區(qū)間更新為2類, 一類是state|i的長度變成r[i]+l[i], 一類是對state的長度在總長度里減去r[i]+l[i], r[i],l[i]為兒子區(qū)間的i顏色實際覆蓋長度。

#include <cstdio> #include <cstring> #include <algorithm>using namespace std;const int maxn=10000+123;//n=10000 struct Segm{int ymin, ymax;//線段覆蓋的區(qū)間,當(dāng)然是離散后的坐標區(qū)間/// 這里保存的是每個值i表示的是i-1到i代表的點之間的距離,因此ymin要+1;long long x;//紀錄當(dāng)前線段在x軸的位置int s;// 記錄當(dāng)前線段的進出 1 -1int color;bool operator < (const Segm & a) const{return x<a.x;} }seg[maxn]; long long T[maxn<<2][8];//實際覆蓋的區(qū)域 int cover[maxn<<2][4];// 記錄被覆蓋的次數(shù) long long len[maxn<<2];//離散后 線段樹節(jié)點表示的實際長度 int n, M, h;struct Map{long long y;//對y離散int ind;bool operator < (const Map & a) const{return y<a.y;} }map[maxn];int bit(int x)/// get highest 1 in bit-number {if(x==0)return 0;int n=31;if((x>>16)==0){n-=16; x<<=16;}if((x>>24)==0){n-=8; x<<=8;}if((x>>28)==0){n-=4; x<<=4;}if((x>>30)==0){n-=2; x<<=2;}return n-(x>>31); }int change[400];void init() {int cnt=0;change['R']=0; change['G']=1; change['B']=2; // memset (seg, 0, sizeof(seg)); // memset (map, 0, sizeof(map));for (int i=0; i<n; ++i){char cc[5]; scanf("%s", cc);seg[i<<1].color=seg[i<<1|1].color=change[cc[0]];scanf("%I64d %I64d %I64d %I64d", &seg[i<<1].x, &map[i<<1].y, &seg[i<<1|1].x, &map[i<<1|1].y);map[i<<1].ind=i<<1; map[i<<1|1].ind=i<<1|1;seg[i<<1].s=1; seg[i<<1|1].s=-1;}sort(map, map+n+n);for (int i=0; i<n+n; ++i){if(i && map[i].y!=map[i-1].y)len[cnt++]=map[i].y-map[i-1].y;//這里在區(qū)間上直接去重int num=map[i].ind>>1;if(map[i].ind&1)seg[num<<1].ymax=seg[num<<1|1].ymax=cnt-1;elseseg[num<<1].ymin=seg[num<<1|1].ymin=cnt;}sort (seg, seg+n+n);h=bit(cnt);M=1<<h;///printf("cnt==%d M==%d\n", cnt, M);memset (T, 0, sizeof(T));memset (cover, 0, sizeof(cover));for (int i=M+cnt; i>=M; --i)len[i]=len[i-M];for (int i=M-1; i>0; --i)len[i]=len[i<<1]+len[i<<1|1];///len[0]=0; }int getcolor(int x) {int state=0;for (int i=0; i<3; ++i){if(cover[x][i]>0)state|=1<<i;}return state; }void merge(const int &x) {int state=getcolor(x);if(state){for (int i=1; i<=7; ++i)T[x][i]=0;T[x][state]=len[x];for (int i=1; i<=7; ++i)if((i|state)!=state){long long tmp=T[x<<1][i]+T[x<<1|1][i];T[x][i|state]+=tmp;T[x][state]-=tmp;// if(state==i)T[x][i]=len[x];// else T[x][i]=(x>=M? 0: T[x<<1][i]+T[x<<1|1][i]);}}else for (int i=1; i<=7; ++i)T[x][i]=T[x<<1][i]+T[x<<1|1][i]; }void Updata(const int &x, const int &cl, const int &v)///根據(jù)顏色更新。 {///printf("x=%d state==%d l==%I64d\n", x, state, len[x]);cover[x][cl]+=v;merge(x); }void IU(int l, int r, int v, int cl) {///不需下傳, 因為+1與-1的區(qū)間是對稱的,有加必有減(不知這樣理解對不)for (l+=M-1, r+=M+1; l^r^1; l>>=1, r>>=1, merge(l), merge(r)){if(~l&1)Updata(l^1, cl, v);if( r&1)Updata(r^1, cl, v);}while (l>1){l>>=1, r>>=1;if(l^r)merge(r);merge(l);} } int id[7]={1, 2, 4, 3, 5, 6, 7};int main () {int cas; scanf("%d", &cas);for (int I=1; I<=cas; ++I){scanf("%d", &n);init();n<<=1;long long area[8]={0};long long now=seg[0].x;for (int i=0; i<n; ++i){//更新區(qū)間插入或刪除線段, 記錄上次的位置Segm &a = seg[i]; // printf("i = %d color= %d\n", i, a.color);for (int i=1; i<=7; ++i){area[i]+=T[1][i]*(a.x-now);if(T[1][i]==0 || a.x==now)continue; // printf("color==%d now==%I64d, x=%I64d, S=%I64d ", i, now, a.x, area[i]); // printf("Ti= %I64d\n", T[1][i]);}//area[]+=T[1]*(a.x-now);//第一為0IU(a.ymin, a.ymax, a.s, a.color);now=a.x;}for (int i=0; i<7; ++i){printf("%I64d\n", area[id[i]]);}}return 0; } /* 3 2 R 0 0 2 2 G 1 1 3 3 3 R 0 0 4 4 G 2 0 6 4 B 0 2 6 6 3 G 2 0 3 8 G 1 0 6 1 B 4 2 7 7*/


總結(jié)

以上是生活随笔為你收集整理的2012网赛杭州赛区的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。