约会安排
寒假來了,又到了小明和女神們約會的季節。?
小明雖為屌絲級碼農,但非常活躍,女神們常常在小明網上的大段發言后熱情回復“呵呵”,所以,小明的最愛就是和女神們約會。與此同時,也有很多基友找他開黑,由于數量實在過于巨大,怎么安排時間便成了小明的一大心事。?
我們已知小明一共有T的空閑時間,期間會有很多女神或者基友來找小明。?
作為一個操作系統曾經怒考71分的大神,小明想到了一個算法,即“首次適應算法”,根據操作系統課本的描述,就是找一段最靠前的符合要求的連續空間分配給每個請求,由此小明做出了一個決定:?
當一個基友來找小明時,小明就根據“首次適應算法”來找一段空閑的時間來和基友約好,如果找到,就說“X,let’s fly”(此處,X為開始時間),否則就說“fly with yourself”;
當女神來找小明時,先使用一次“首次適應算法”,如果沒有找到,小明就冒著木嘰嘰的風險無視所有屌絲基友的約定,再次使用“無視基友首次適應算法”,兩次只要有一次找到,就說“X,don’t put my gezi”(此處,X為開始時間),否則就說“wait for me”?
當然,我們知道小明不是一個節操負無窮的人,如果和女神約會完,還有剩余時間,他還是會和原來約好的基友去dota的。(舉個例子:小西(屌絲)和小明約好在1~5這個時間單位段內打dota,這時候,女神來和小明預約長度為3的時間段,那么最終就是1~3小明去和女神約會,搞定后在4~5和小西打dota)?
小明偶爾也會想要學習新知識,此時小明就會把某一個時間區間的所有已經預定的時間全部清空用來學習并且怒吼“I am the hope of chinese chengxuyuan!!”,不過小明一般都是三分鐘熱度,再有人來預定的話,小明就會按耐不住寂寞把學習新知識的時間分配出去。
Input
輸入第一行為CASE,表示有CASE組測試數據;?
每組數據以兩個整數T,N開始,T代表總共的時間,N表示預約請求的個數;?
接著的N行,每行表示一個女神或者基友的預約,“NS QT”代表一個女神來找小明約一段長為QT的時間,“DS QT”則代表一個屌絲的長為QT的請求,當然也有可能是小明想學知識了,“STUDY!! L R”代表清空L~R區間內的所有請求。?
[Technical Specification]?
1. 1 <= CASE <= 30?
2. 1 <= T, N <= 100000?
3. 1 <= QT <= 110000?
4. 1 <= L <= R <=T
Output
對于每一個case,第一行先輸出“Case C:”代表是第幾個case,然后N行,每行對應一個請求的結果(參照描述)。?
輸出樣本(可復制此處):?
“X,let's fly”,”fly with yourself”,”X,don't put my gezi”,”wait for me”,”I am the hope of chinese chengxuyuan!!”?
Sample Input
1 5 6 DS 3 NS 2 NS 4 STUDY!! 1 5 DS 4 NS 2Sample Output
Case 1: 1,let's fly 4,don't put my gezi wait for me I am the hope of chinese chengxuyuan!! 1,let's fly 1,don't put my geziC++版本一
#include<bits\stdc++.h> using namespace std; typedef long long LL; const int maxn=1e5+7; int ll[maxn<<2],rr[maxn<<2],mm[maxn<<2]; int ill[maxn<<2],irr[maxn<<2],imm[maxn<<2];void build(int rt,int l,int r) {ll[rt]=rr[rt]=mm[rt]=r-l+1;ill[rt]=irr[rt]=imm[rt]=r-l+1;if(l==r) return ;int mid=(l+r)>>1;build(rt<<1,l,mid);build(rt<<1|1,mid+1,r); }void push_up(int rt,int l,int r) {int mid=(r+l)>>1;mm[rt]=max(mm[rt<<1],mm[rt<<1|1]);mm[rt]=max(mm[rt],rr[rt<<1]+ll[rt<<1|1]);ll[rt]=ll[rt<<1];rr[rt]=rr[rt<<1|1];if(ll[rt]==mid-l+1) ll[rt]+=ll[rt<<1|1];if(rr[rt]==r-mid) rr[rt]+=rr[rt<<1];imm[rt]=max(imm[rt<<1],imm[rt<<1|1]);imm[rt]=max(imm[rt],irr[rt<<1]+ill[rt<<1|1]);ill[rt]=ill[rt<<1];irr[rt]=irr[rt<<1|1];if(ill[rt]==mid-l+1) ill[rt]+=ill[rt<<1|1];if(irr[rt]==r-mid) irr[rt]+=irr[rt<<1]; }void push_down(int rt,int l,int r) {int mid=(l+r)>>1;if(mm[rt]==r-l+1){ll[rt<<1]=rr[rt<<1]=mm[rt<<1]=mid-l+1;ll[rt<<1|1]=rr[rt<<1|1]=mm[rt<<1|1]=r-mid;}else if(mm[rt]==0){ll[rt<<1]=rr[rt<<1]=mm[rt<<1]=0;ll[rt<<1|1]=rr[rt<<1|1]=mm[rt<<1|1]=0;}if(imm[rt]==r-l+1){ill[rt<<1]=irr[rt<<1]=imm[rt<<1]=mid-l+1;ill[rt<<1|1]=irr[rt<<1|1]=imm[rt<<1|1]=r-mid;}else if(imm[rt]==0){ill[rt<<1]=irr[rt<<1]=imm[rt<<1]=0;ill[rt<<1|1]=irr[rt<<1|1]=imm[rt<<1|1]=0;} }// 0---DS 1---NS 2---STUDY void update(int rt,int l,int r,int ul,int ur,int flag) {if(ul<=l&&ur>=r){if(flag==1)ll[rt]=rr[rt]=mm[rt]=ill[rt]=irr[rt]=imm[rt]=0;else if(flag==0)ll[rt]=rr[rt]=mm[rt]=0;elsell[rt]=rr[rt]=mm[rt]=ill[rt]=irr[rt]=imm[rt]=r-l+1;return ;}push_down(rt,l,r);int mid=(l+r)>>1;if(ul<=mid) update(rt<<1,l,mid,ul,ur,flag);if(ur>mid) update(rt<<1|1,mid+1,r,ul,ur,flag);push_up(rt,l,r); }// find the left end of a corresponding interval // 0---DS 1---NS int query(int rt,int l,int r,int dur,int flag) {if(l==r) return l;int mid=(l+r)>>1;push_down(rt,l,r);if(flag){if(imm[rt<<1]>=dur) return query(rt<<1,l,mid,dur,flag);else if(irr[rt<<1]+ill[rt<<1|1]>=dur) return mid-irr[rt<<1]+1;else return query(rt<<1|1,mid+1,r,dur,flag);}else{if(mm[rt<<1]>=dur) return query(rt<<1,l,mid,dur,flag);else if(rr[rt<<1]+ll[rt<<1|1]>=dur) return mid-rr[rt<<1]+1;else return query(rt<<1|1,mid+1,r,dur,flag);} } char option[10]; int main() {/************freopen("in.txt","r",stdin);freopen("out1.txt","w",stdout);/********************/int T,kase=0;int t,n,dur;scanf("%d",&T);while(++kase<=T){scanf("%d%d",&t,&n);printf("Case %d:\n",kase);build(1,1,t);for(int i=0;i<n;i++){scanf("%s",option);if(option[0]=='D'){scanf("%d",&dur);if(mm[1]<dur) puts("fly with yourself");else{int res=query(1,1,t,dur,0);printf("%d,let's fly\n",res);update(1,1,t,res,res+dur-1,0);}}else if(option[0]=='N'){scanf("%d",&dur);if(mm[1]>=dur){int res=query(1,1,t,dur,0);printf("%d,don't put my gezi\n",res);update(1,1,t,res,res+dur-1,1);}else if(imm[1]>=dur){int res=query(1,1,t,dur,1);printf("%d,don't put my gezi\n",res);update(1,1,t,res,res+dur-1,1);}elseputs("wait for me");}else{int l,r;scanf("%d%d",&l,&r);update(1,1,t,l,r,2);puts("I am the hope of chinese chengxuyuan!!");}}}return 0; }C版本二
WA
鬼知道問題在哪
仿照版本一
#include <iostream> #include <stdio.h> #include <algorithm> #include <string.h> #include <math.h> using namespace std; const int N=100000+100; int t,n,mm; struct node{int dl,dr;int nl,nr;int dsum;int nsum;}tree[N<<2];void DPushup(int i,int l,int r){int m=(r+l)>>1;tree[i].dsum=max(tree[i<<1].dsum,tree[i<<1|1].dsum);tree[i].dsum=max(tree[i].dsum,tree[i<<1].dr+tree[i<<1|1].dl);tree[i].dl=tree[i<<1].dl;tree[i].dr=tree[i<<1|1].dr;if(tree[i].dl==m-l+1) tree[i].dl+=tree[i<<1|1].dl;if(tree[i].dr==r-m) tree[i].dr+=tree[i<<1].dr;} void NPushup(int i,int l,int r){int m=(r+l)>>1;tree[i].nsum=max(tree[i<<1].nsum,tree[i<<1|1].nsum);tree[i].nsum=max(tree[i].nsum,tree[i<<1].nr+tree[i<<1|1].nl);tree[i].nl=tree[i<<1].nl;tree[i].nr=tree[i<<1|1].nr;if(tree[i].nl==m-l+1) tree[i].nl+=tree[i<<1|1].nl;if(tree[i].nr==r-m) tree[i].nr+=tree[i<<1].nr;} void DPushdown(int i,int l,int r){int m=(l+r)>>1;if(tree[i].dsum==r-l+1){tree[i<<1].dsum=tree[i<<1].dl=tree[i<<1].dr=m-l+1;tree[i<<1|1].dsum=tree[i<<1|1].dl=tree[i<<1|1].dr=r-m;}else if(tree[i].dsum==0){tree[i<<1].dsum=tree[i<<1].dl=tree[i<<1].dr=0;tree[i<<1|1].dsum=tree[i<<1|1].dl=tree[i<<1|1].dr=0;} } void NPushdown(int i,int l,int r){int m=(l+r)>>1;if(tree[i].nsum==r-l+1){tree[i<<1].nsum=tree[i<<1].nl=tree[i<<1].nr=m-l+1;tree[i<<1|1].nsum=tree[i<<1|1].nl=tree[i<<1|1].nr=r-m;}else if(tree[i].nsum==0){tree[i<<1].nsum=tree[i<<1].nl=tree[i<<1].nr=0;tree[i<<1|1].nsum=tree[i<<1|1].nl=tree[i<<1|1].nr=0;} } void Build(int i,int l,int r){tree[i].dl=tree[i].dr=tree[i].dsum=r-l+1;tree[i].nl=tree[i].nr=tree[i].nsum=r-l+1;if(l!=r){int m=(l+r)>>1;Build(i<<1,l,m);Build(i<<1|1,m+1,r);} } int DQuery(int i,int l,int r,int L ){if(l==r){return l;}int m=(l+r)>>1;DPushdown(i,l,r);if(tree[i<<1].dsum>=L)return DQuery(i<<1,l,m,L);else if(tree[i<<1].dr+tree[i<<1|1].dl>=L)return m-tree[i<<1].dr+1;elsereturn DQuery(i<<1|1,m+1,r,L); } int NQuery(int i,int l,int r,int L){if(l==r){return l;}int m=(l+r)>>1;NPushdown(i,l,r);if(tree[i<<1].nsum>=L)return NQuery(i<<1,l,m,L);else if(tree[i<<1].nr+tree[i<<1|1].nl>=L)return m-tree[i<<1].nr+1;elsereturn NQuery(i<<1|1,m+1,r,L); } void DUpdata(int i,int l,int r,int L,int R){if(L<=l&&r<=R){tree[i].dsum=tree[i].dl=tree[i].dr=0;return;}DPushdown(i,l,r);int m=(l+r)>>1;if(L<=m)DUpdata(i<<1,l,m,L,R);if(m<R)DUpdata(i<<1|1,m+1,r,L,R);DPushup(i,l,r); } void NUpdata(int i,int l,int r,int L,int R){if(L<=l&&r<=R){tree[i].nsum=tree[i].nl=tree[i].nr=tree[i].dsum=tree[i].dl=tree[i].dr=0;return;}NPushdown(i,l,r);DPushdown(i,l,r);int m=(l+r)>>1;if(L<=m)NUpdata(i<<1,l,m,L,R);if(m<R)NUpdata(i<<1|1,m+1,r,L,R);NPushup(i,l,r);DPushup(i,l,r); } void SUpdata(int i,int l,int r,int L,int R){if(L<=l&&r<=R){tree[i].dsum=tree[i].dl=tree[i].dr=tree[i].nsum=tree[i].nl=tree[i].nr=r-l+1;return;}NPushdown(i,l,r);DPushdown(i,l,r);int m=(l+r)>>1;if(L<=m)SUpdata(i<<1,l,m,L,R);if(m<R)SUpdata(i<<1|1,m+1,r,L,R);NPushup(i,l,r);DPushup(i,l,r); } int main() {scanf("%d",&t);for(int T=1;T<=t;T++){printf("Case %d:\n",T);scanf("%d%d",&n,&mm);char c[10];int q,x,y;Build(1,1,n);while(mm--){scanf("%s",c);if(c[0]=='D'){scanf("%d",&q);if(tree[1].dsum>=q){int a=DQuery(1,1,n,q);cout <<a<< ",let’s fly" << endl;DUpdata(1,1,n,a,a+q-1);}elsecout << "fly with yourself" << endl;}else if(c[0]=='N'){scanf("%d",&q);if(tree[1].dsum>=q){int a=DQuery(1,1,n,q);NUpdata(1,1,n,a,a+q-1);cout <<a<< ",don’t put my gezi" << endl;}else if(tree[1].nsum>=q){int a=NQuery(1,1,n,q);NUpdata(1,1,n,a,a+q-1);cout <<a<< ",don’t put my gezi" << endl;}elsecout << "wait for me" << endl;}else{scanf("%d%d",&x,&y);SUpdata(1,1,n,x,y);cout << "I am the hope of chinese chengxuyuan!!" << endl;}}}//cout << "Hello world!" << endl;return 0; }?
總結