1. 程式人生 > >Noip2017複賽遊記(爆炸記)

Noip2017複賽遊記(爆炸記)

2017.11.10,7:00。出發。

路上是很愉快的(呃。。。好吧),大家分享了一些自己關於各種演算法、程式碼的感想與經驗,然後就是唱歌時間QAQ。在高速的服務站上休息了一小小之後就又繼續上路了。剩下的路程中各自說了說圖論,然後就都睡著了(畢竟還是困23333)。

到了,大概11:30,報到、領證(手動滑稽)啥的都很順利,沒有擁擠也基本上沒有排隊,很愉快的去吃飯(路上對著美其名曰“澡票”的票子陷入了沉思),之後去宿舍。意想不到的是,女生住的是男生宿舍,而男生住的是女生宿舍喲。

下午,會見了幾位大佬,又去商店浪,之後就在宿舍……學習的學習,遊戲的遊戲,浪的浪。。。據此生一新詞名曰“王者C++”233。

晚上,開會,試機,本蒻首先要吐槽輸入法,一個大屁股破電腦裝那麼多輸入法幹啥,害的本弱每次輸完漢字後都要按好幾次Ctrl+Shift切換,後來就懶了,也煩了,索性Ctrl+空格直接快速切回系統英文;第二吐槽一下解析度,程式碼看起來是畫素的真的沒法說啥了;第三吐槽我那按不動的鍵盤,後來要求換了一套;第四吐槽堂堂一個考場為毛系統還是Xp(非個人對Xp的偏見)。試了試Compile,Run,Debug等,都還好,又搞了搞long long的I64和ll以確保正常(畢竟學校微機室裡有個大佬的電腦的lld和I64d被Windows反過來用了。。。),同時低頭膜拜寫反過的大佬。又敲了幾個模板(如需練習模板請移步洛谷

https://www.luogu.org/problem/lists?name=%E6%A8%A1%E6%9D%BF),以防手生(然額事實證明並沒有什麼卵用)。ps:本弱第一排。

Day1。

T1小凱的疑惑(題目連結 ),這就是送一群大佬退役的小學奧數。2017你的NOIP之小學奧數,回小學重唸吧(滑稽)。首先公式送上:A*B-A-B。一上來各路大仙都那個噼裡啪啦一頓敲啊,然額第一排一片肅靜。。。十五分鐘後本蒟蒻推出一個別具一格的公式,送上:answer=max(a,b)*(min(a,b)-1)-min(a,b)。於是t1約25分鐘完成。下面送上本弱另類程式碼:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
long long a,b;
long long maxn,minn,tmp,ans;
int main()
{
	freopen("math.in","r",stdin);
	freopen("math.out","w",stdout);
	scanf("%lld%lld",&a,&b);
	maxn=max(a,b);
	minn=min(a,b);
	tmp=minn-1;
	ans=maxn*tmp-minn;
	printf("%lld",ans);
	return 0;
}

大神圍觀勿噴,其實推導過來都是一樣的,只是本蒻的用了幾次比較而已,反正是AC了啦。接下來是標準的程式碼:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
long long a,b;
int main()
{	freopen("math.in","r",stdin);
	freopen("math.out","w",stdout);
	scanf("%lld%lld",&a,&b);
	printf("%lld\n",a*b-a-b);
	return 0;
}

T2時間複雜度(題目連結)老師說是模擬,網路上的大佬們也有說是棧的,本弱認真地審了審題,發現滿分操作對於自己完全是tan270°,果斷取了30%的資料騙了三十分(其實這30分好寫),送上30分的時間複雜度:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int t,l,cnt=0,x,s;
char start[2],ii[3],y[4],str[10];
int main()
{
	freopen("complexity.in","r",stdin);
	freopen("complexity.out","w",stdout);
	scanf("%d",&t);
	while(t--)
	{
		cnt=0;
		scanf("%d",&l);
		scanf("%s",str+1);
		for(int i=1; i<=l/2; i++)
		{
			scanf("%s",start+1);
			scanf("%s",ii+1);
			scanf("%d",&x);
			scanf("%s",y+1);
			if(y[1]=='n')
				cnt++;
		}
		for(int i=l/2+1; i<=l; i++)
			scanf("%s",start+1);
		if(cnt==0)
		{
			s=1;
			if(s==str[3]-'0')
				printf("Yes\n");
			else 
				printf("No\n");
		}
		else 
		{
			if(cnt==str[5]-'0')
				printf("Yes\n");
			else 
				printf("No\n");
		}
	}
	return 0;
}

接下來是洛谷的標程(僅供參考學習用,請不要惡意抄襲):

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <string>
#include <stack>

using namespace std;

bool stat[26];

inline char t(const string& original) {
    return original[0] - 'a';
}

inline bool isInt(const string& str) {
    return str[0] >= '0' && str[0] <= '9';
}

inline int getPV(const string& str) {
    if(isInt(str)) 
        return atoi(str.c_str());
    else
        return 1000000;
}

struct stackContent {
    int complexity;
    char var;
    bool parentEntryImpossible;
};

int main() {
    int n;
    cin >> n;
    for(int i=1; i<=n; i++) {
        memset(stat, 0, sizeof(stat));

        int lineCnt, expectedComplexity;
        cin >> lineCnt;

        string complexity;
        cin >> complexity;

        if(complexity[2] == '1')
            expectedComplexity = 0;
        else
            sscanf(complexity.c_str(), "O(n^%d)", &expectedComplexity);

        string currentToken, last_t_A; 
        bool validFlag = true;

        int currentComplexity = 0, maxComplexity = 0;
        bool parentEntryImpossible = false;
        stack<stackContent> complexityStack;
        for(int j=1; j<=lineCnt; j++) {
            cin >> currentToken;
            if(currentToken == "F") {
                string t_A, t_B, t_C;
                cin >> t_A >> t_B >> t_C;
                if(!validFlag) continue;

                if(stat[t(t_A)]) {
                    validFlag = false;
                    continue;
                }

                complexityStack.push((stackContent){currentComplexity, t_A[0], parentEntryImpossible});

                if(parentEntryImpossible)
                    parentEntryImpossible = true;
                else if(getPV(t_B) > getPV(t_C))
                    parentEntryImpossible = true;
                else if(t_B != "n" && t_C == "n") {
                    currentComplexity++;
                    maxComplexity = max(maxComplexity, currentComplexity);
                }
                
                stat[t(t_A)] = true;
            } else if(currentToken == "E") {
                if(!validFlag) continue;

                if(complexityStack.size() == 0) {
                    validFlag = false;
                    continue;
                }

                currentComplexity = complexityStack.top().complexity;
                stat[complexityStack.top().var - 'a'] = false;
                parentEntryImpossible = complexityStack.top().parentEntryImpossible;
                complexityStack.pop();
            }
        }

        if(!validFlag || complexityStack.size() != 0)
            cout << "ERR" << endl;
        else {
            if(maxComplexity == expectedComplexity) 
                cout << "Yes" << endl;
            else
                cout << "No" << endl;
        }
    }

    return 0;
}

這可能是標準答案:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
char s[20],q[105],nm[105];
int tt,l,x[105],y[105],st[105],mch[105],ll,v[105];
bool vis[30];
void work()
{	scanf("%d",&l);
	scanf("%s",s);
	int ans=0,ac=0,sum=0;
	if(s[2]=='1')ans=0;
	else for(int i=4;s[i]!=')';i++)ans=ans*10+s[i]-'0';
	memset(vis,false,sizeof vis);
	for(int i=1;i<=l;i++)
	{	scanf("%s",s);
		q[i]=s[0];
		if(q[i]=='F')
		{	scanf("%s",s);
			nm[i]=s[0];
			scanf("%s",s);
			if(s[0]=='n')x[i]=-1;
			else
			{	x[i]=0,ll=strlen(s);
				for(int j=0;j<ll;j++)x[i]=x[i]*10+s[j]-'0';
			}
			scanf("%s",s);
			if(s[0]=='n')y[i]=-1;
			else
			{	y[i]=0,ll=strlen(s);
				for(int j=0;j<ll;j++)y[i]=y[i]*10+s[j]-'0';
			}
		}
	}
	int t=0;
	for(int i=1;i<=l;i++)
	{	if(q[i]=='F')st[++t]=i;
		else
		{	if(t==0)
			{	printf("ERR\n");
				return;
			}
			mch[i]=st[t],mch[st[t]]=i,--t;
		}
	}
	if(t)
	{	printf("ERR\n");
		return;
	}
	for(int i=1;i<=l;i++)
	{	if(q[i]=='F')
		{	if(vis[nm[i]-'a'])
			{	printf("ERR\n");
				return;
			}
			vis[nm[i]-'a']=true;
			if(x[i]==-1)
			{	if(y[i]==-1)v[i]=0;
					else v[i]=-1;
			}else
			{	if(y[i]==-1)v[i]=1;
					else v[i]=x[i]<=y[i]?0:-1;
			}
		}else vis[nm[mch[i]]-'a']=false;
	}
	for(int i=1;i<=l;i++)
	{	if(q[i]=='F')
		{	if(v[i]==-1)i=mch[i];
			else
			{	sum+=v[i];
				ac=max(ac,sum);
			}
		}else sum-=v[mch[i]];
	}
	if(ac==ans)printf("Yes\n");
		else printf("No\n");
}
int main()
{	freopen("complexity.in","r",stdin);
	freopen("complexity.out","w",stdout);
	scanf("%d",&tt);
	while(tt--)work();
	return 0;
}

         T3逛公園(題目連結)好好的一個dp硬是寫成克魯斯卡爾。。。神醉啊~~~也有大佬寫最短路。。。

於是0分

不知道從哪挖到的程式碼:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
const int inf=1e9;
struct node
{	int p,w;
};
struct cmp
{	inline bool operator ()(const node &a,const node &b)
	{return a.w>b.w;}
};
priority_queue<node,vector<node>,cmp>h;
int q[100005],tt,n,m,k,p,x,y,z,dis[100005],dis2[100005],mn1[100005],mn2[100005];
int bel[100005],siz[100005],low[100005],dfn[100005],cnt,ct,st[100005],tp;
int f[100005][53],tmp[100005];
bool vis[100005],ins[100005];
inline bool cmp2(int a,int b){return dis[a]==dis[b]?dfn[a]<dfn[b]:dis[a]<dis[b];}
struct cmp3
{	inline bool operator ()(int a,int b)
	{return dfn[tmp[a]]>dfn[tmp[b]];}
};
priority_queue<int,vector<int>,cmp3>d;
struct line
{	int v,w,next;
};
struct graph
{	line e[200005];
	int b[100005],t;
	inline void init()
	{	memset(b,-1,sizeof b);
		t=-1;
	}
	inline void build(int x,int y,int w)
	{	e[++t].v=y;
		e[t].w=w;
		e[t].next=b[x];
		b[x]=t;
	}
	void tarjan(int u)
	{	low[u]=dfn[u]=++cnt;
		vis[u]=ins[u]=true;
		st[++tp]=u;
		for(int o=b[u];o!=-1;o=e[o].next)
		{	if(!vis[e[o].v])
			{	tarjan(e[o].v);
				low[u]=min(low[u],low[e[o].v]);
			}else if(ins[e[o].v])low[u]=min(low[u],dfn[e[o].v]);
		}
		if(low[u]==dfn[u])
		{	siz[++ct]=0;
			int k=st[tp--];
			for(;;)
			{	bel[k]=ct,++siz[ct],ins[k]=false;
				if(k==u)break;
				k=st[tp--];
			}
		}
	}
	void dotarjan()
	{	cnt=ct=tp=0;
		memset(vis,false,sizeof vis);
		memset(ins,false,sizeof ins);
		for(int i=1;i<=n;i++)if(!vis[i])tarjan(i);
	}
	void dijkstra(int st,int *dis)
	{	memset(vis,false,sizeof vis);
		for(int i=1;i<=n;i++)dis[i]=inf;
		dis[st]=0;
		h.push((node){st,0});
		while(!h.empty())
		{	node a=h.top();
			h.pop();
			if(vis[a.p])continue;
			int u=a.p;
			vis[u]=true;
			for(int o=b[u];o!=-1;o=e[o].next)
			{	if(dis[u]+e[o].w<dis[e[o].v])
				{	dis[e[o].v]=dis[u]+e[o].w;
					h.push((node){e[o].v,dis[e[o].v]});
				}
			}
		}
	}
	void topo()
	{	memset(low,0,sizeof low);
		for(int i=1;i<=n;i++)if(siz[bel[i]]==1)
			for(int o=b[i];o!=-1;o=e[o].next)++low[e[o].v];
		int l=1,r=0;
		for(int i=1;i<=n;i++)if(low[i]==0)q[++r]=i;
		while(l<=r)
		{	int u=q[l++];
			for(int o=b[u];o!=-1;o=e[o].next)
			{	--low[e[o].v];
				if(low[e[o].v]==0)q[++r]=e[o].v;
			}
		}
		for(int i=1;i<=r;i++)dfn[q[i]]=i;
	}
	void dp()
	{	int t=0;
		for(int i=1;i<=n;i++)if(siz[bel[i]]==1)tmp[++t]=i;
		sort(tmp+1,tmp+t+1,cmp2);
		for(int i=1;i<=n;i++)for(int j=0;j<=k;j++)f[i][j]=0;
		f[1][0]=1;
		int l=1,r=1;
		for(int i=0;i<=dis[n]+k;i++)
		{	while(r<t&&dis[tmp[r+1]]==i)++r;
			while(l<=r&&i-dis[tmp[l]]>k)++l;
			if(l>r)
			{	r=l,i=dis[tmp[l]]-1;
				continue;
			}
			d.push(l);
			for(int z=l+1;z<=r;z++)if(dis[tmp[z]]!=dis[tmp[z-1]])d.push(z);
			while(!d.empty())
			{	int z=d.top();
				d.pop();
				if(z<r&&dis[tmp[z+1]]==dis[tmp[z]])d.push(z+1);
				int u=tmp[z],j=i-dis[u];
				for(int o=b[u];o!=-1;o=e[o].next)
				{	if(i+e[o].w<=dis[e[o].v]+k)
					f[e[o].v][i+e[o].w-dis[e[o].v]]=(f[e[o].v][i+e[o].w-dis[e[o].v]]+f[u][j])%p;
				}
			}
		}
	}
	void dp2()
	{	int t=0;
		for(int i=1;i<=n;i++)if(siz[bel[i]]==1)tmp[++t]=i;
		sort(tmp+1,tmp+t+1,cmp2);
		for(int i=1;i<=n;i++)for(int j=0;j<=k;j++)f[i][j]=0;
		f[1][0]=1;
		int l=1,r=1;
		for(int i=0;i<=dis[n]+k;i++)
		{	while(r<t&&dis[tmp[r+1]]==i)++r;
			while(l<=r&&i-dis[tmp[l]]>k)++l;
			if(l>r)
			{	r=l,i=dis[tmp[l]]-1;
				continue;
			}
			for(int z=l;z<=r;z++)
			{	int u=tmp[z],j=i-dis[u];
				for(int o=b[u];o!=-1;o=e[o].next)
				{	if(i+e[o].w<=dis[e[o].v]+k)
					f[e[o].v][i+e[o].w-dis[e[o].v]]=(f[e[o].v][i+e[o].w-dis[e[o].v]]+f[u][j])%p;
				}
			}
		}
	}
}aa,bb,cc;
inline int read()
{	int x=0;
	char c=getchar();
	while(c<'0'||c>'9')c=getchar();
	while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();
	return x;
}
void work()
{	aa.init(),bb.init(),cc.init();
	n=read(),m=read(),k=read(),p=read();
	int zz=0;
	for(int i=1;i<=m;i++)
	{	x=read(),y=read(),z=read();
		aa.build(x,y,z),bb.build(y,x,z);
		if(z==0)++zz,cc.build(x,y,0);
	}
	cc.dotarjan();
	aa.dijkstra(1,dis);
	bb.dijkstra(n,dis2);
	for(int i=1;i<=ct;i++)mn1[i]=mn2[i]=inf;
	for(int i=1;i<=n;i++)mn1[bel[i]]=min(mn1[bel[i]],dis[i]),mn2[bel[i]]=min(mn2[bel[i]],dis2[i]);
	for(int i=1;i<=ct;i++)if(siz[i]>1&&mn1[i]+mn2[i]<=dis[n]+k)
	{	printf("-1\n");
		return;
	}
	cc.topo();
	if(zz)aa.dp();else aa.dp2();
	int ac=0;
	for(int i=0;i<=k;i++)ac=(ac+f[n][i])%p;
	printf("%d\n",ac);
}
int main()
{	freopen("park.in","r",stdin);
	freopen("park.out","w",stdout);
	tt=read();
	while(tt--)work();
	return 0;
}

         下午。在宿舍裡打牌,還沒開始,老師推門而入,場面一度十分尷尬。。。

         晚上,和同遊大佬在操場狂歡。

Day2。

         T1乳酪(題目連結)本弱的純數學方法非for迴圈暴力運算竟然搞到了五分,,有的大佬說這是要用圖做的。

#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cstring>
using namespace std;
struct node
{
    long long next,to;
}    e[2000005];
struct node1
{
    long long x,y,z;
}    a[1005];
long long head[1005],cnt,vis[1005];
inline void insert(long long u,long long v)
{
    e[++cnt].next=head[u];
    head[u]=cnt;
    e[cnt].to=v;
}
inline void dfs(long long now)
{
    vis[now]=1;
    for(long long i=head[now];i;i=e[i].next)
    {
        if(vis[e[i].to])    continue;
        dfs(e[i].to);
    }
}
int main()
{
    long long t,S,T,n,m,k;
    scanf("%lld",&t);
    while(t--)
    {
        cnt=0;
        memset(vis,0,sizeof(vis));
        memset(head,0,sizeof(head));
        scanf("%lld%lld%lld",&n,&m,&k);
        S=n+1,T=n+2;
        for(long long i=1;i<=n;i++)
        {
            scanf("%lld%lld%lld",&a[i].x,&a[i].y,&a[i].z);
            if(a[i].z<=k)    
            {
                insert(S,i);
                insert(i,S);
            }
            if(a[i].z>=m-k)
            {
                insert(T,i);
                insert(i,T);
            }
        }
        for(long long i=1;i<=n;i++)
            for(long long j=i+1;j<=n;j++)
            {
                if((a[j].x-a[i].x)*(a[j].x-a[i].x)+(a[j].y-a[i].y)*(a[j].y-a[i].y)+(a[j].z-a[i].z)*(a[j].z-a[i].z)<=4*k*k)
                {
                    insert(i,j);
                    insert(j,i);
                }
            }
        dfs(S);
        if(vis[T])
        {
            printf("Yes\n");
        }
        else
        {
            printf("No\n");
        }
    }
    
    return 0;
}

         T2寶藏(題目連結)又覺得是個不會找深度的最小生成樹。。。

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
typedef long long ll;
int n,m,tot,ans;
 
int map[110][110],dis[110][110],Log[4100];
int f[15][4100],g[4100],ref[4100],v[15],p[15];
inline int min(const int &a,const int &b)
{
    return a<b?a:b;
}
 
int main()
{
    //freopen("treasure.in","r",stdin);
    //freopen("treasure.out","w",stdout);
    scanf("%d%d",&n,&m);
    register int i,j,a,b,c,x;
    for(i=0;i<n;i++) for(j=0;j<n;j++) map[i][j]=60000000;
    for(i=1;i<=m;i++)
    {
        scanf("%d%d%d",&a,&b,&c),a--,b--;
        map[a][b]=map[b][a]=min(map[a][b],c);
    }
    for(i=0;i<n;i++) Log[1<<i]=i;
    memset(f,0x3f,sizeof(f));
    for(i=0;i<n;i++) f[0][1<<i]=0;
    for(i=0;i<n;i++) for(x=0;x<(1<<n);x++)
    {
        tot=0;
        for(a=0;a<n;a++) if(!(x&(1<<a)))
        {
            v[tot]=60000000,p[tot]=1<<a;
            for(j=x;j;j-=j&-j)
            {
                b=Log[j&-j];
                v[tot]=min(v[tot],map[a][b]*(i+1));
            }
            tot++;
        }
        for(j=1;j<(1<<tot);j++)
        {
            g[j]=g[j-(j&-j)]+v[Log[j&-j]];
            ref[j]=ref[j-(j&-j)]|p[Log[j&-j]];
            f[i+1][x|ref[j]]=min(f[i+1][x|ref[j]],f[i][x]+g[j]);
        }
    }
    ans=1<<30;
    for(i=0;i<=n;i++)    ans=min(ans,f[i][(1<<n)-1]);
    printf("%d",ans);
    return 0;
}

T3列隊(題目連結)What?啥玩意?模擬?這麼大的資料範圍?認真的取了小範圍模擬了一下,於是第二組樣例…一開始幾十個數都是對的…後來就有0出現…到檔案末尾只剩亂糟糟的全錯了…於是又爆零

是啥玩意蒟蒻也沒看懂

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int maxn=300010;
typedef long long ll;
struct node
{
    int ch[2],siz,val,org,tag;
}s[maxn<<1];
int n,m,q,tot;
int rx,ry[maxn];
//px指最右面那列,py指每一行
int bel[maxn],x[maxn],y[maxn];
ll ans[maxn];
inline int rd()
{
    int ret=0;  char gc=getchar();
    while(gc<'0'||gc>'9') gc=getchar();
    while(gc>='0'&&gc<='9')   ret=ret*10+gc-'0',gc=getchar();
    return ret;
}
inline void pushdown(int x)
{
    if(s[x].tag)
    {
        if(s[x].ch[0])  s[s[x].ch[0]].val+=s[x].tag,s[s[x].ch[0]].tag+=s[x].tag;
        if(s[x].ch[1])  s[s[x].ch[1]].val+=s[x].tag,s[s[x].ch[1]].tag+=s[x].tag;
        s[x].tag=0;
    }
}
inline void pushup(int x)
{
    s[x].siz=s[s[x].ch[0]].siz+s[s[x].ch[1]].siz+1;
}
inline void rotate(int &x,int d)
{
    int y=s[x].ch[d];
    pushdown(x),pushdown(y);
    s[x].ch[d]=s[y].ch[d^1],s[y].ch[d^1]=x;
    pushup(x),pushup(y);
    x=y;
}
inline void maintain(int &x,int d)
{
    if(s[s[s[x].ch[d]].ch[d]].siz>s[s[x].ch[d^1]].siz)   rotate(x,d);
    else    if(s[s[s[x].ch[d]].ch[d^1]].siz>s[s[x].ch[d^1]].siz) rotate(s[x].ch[d],d^1),rotate(x,d);
    else    return ;
    maintain(s[x].ch[d],d),maintain(s[x].ch[d^1],d^1);
    maintain(x,d),maintain(x,d^1);
}
void insert(int &x,int y,int z)
{
    if(!x)
    {
        x=++tot,s[x].siz=1,s[x].ch[0]=s[x].ch[1]=s[x].tag=0,s[x].val=y,s[x].org=z;
        return ;
    }
    pushdown(x);
    int d=(y>s[x].val);
    insert(s[x].ch[d],y,z),pushup(x);
    maintain(x,d);
}
void del(int &x,int y)
{
    s[x].siz--,pushdown(x);
    if(s[y].val>s[x].val)    del(s[x].ch[1],y);
    else if(s[y].val<s[x].val)   del(s[x].ch[0],y);
    else
    {
        if(!s[x].ch[0]||!s[x].ch[1])
        {
            x=s[x].ch[0]^s[x].ch[1];
            return ;
        }
        int u=s[x].ch[1];   pushdown(u);
        while(s[u].ch[0])   u=s[u].ch[0],pushdown(u);
        s[x].org=s[u].org,s[x].val=s[u].val;
        del(s[x].ch[1],u);
    }
}
void updata(int x,int y)
{
    if(!x)  return ;
    pushdown(x);
    if(s[x].val>=y)
    {
        s[x].val++;
        if(s[x].ch[1])  s[s[x].ch[1]].val++,s[s[x].ch[1]].tag++;
        updata(s[x].ch[0],y);
    }
    else    updata(s[x].ch[1],y);
}
inline int findmax(int x)
{
    pushdown(x);
    while(s[x].ch[1])   x=s[x].ch[1],pushdown(x);
    return x;
}
inline ll point(int a,int b) {return ll(a-1)*m+b;}
void dfs(int x,int t)
{
    if(!x)  return ;
    pushdown(x);
    if(!t)  ans[s[x].org]=point(s[x].val,m);
    else    ans[s[x].org]=point(t,s[x].val);
    dfs(s[x].ch[0],t),dfs(s[x].ch[1],t);
}
int find(int x,int y)
{
    if(!x)  return 0;
    pushdown(x);
    if(y>s[x].val)   return find(s[x].ch[1],y);
    if(y<s[x].val)   return find(s[x].ch[0],y);
    return x;
}
int main()
{
    //freopen("phalanx.in","r",stdin);
    //freopen("phalanx.out","w",stdout);
    n=rd(),m=rd(),q=rd();
    int i;
    for(i=1;i<=q;i++)
    {
        bel[i]=i;
        x[i]=rd(),y[i]=rd();
    }
    for(i=q;i>=1;i--)
    {
        int t=findmax(rx);
        if(s[t].val==n)
        {
            bel[s[t].org]=i,del(rx,t);
        }
        updata(rx,x[i]);
        updata(ry[x[i]],y[i]);
        t=findmax(ry[x[i]]);
        if(s[t].val==m)
        {
            del(ry[x[i]],t),insert(rx,x[i],s[t].org);
        }
        if(y[i]<m)   insert(ry[x[i]],y[i],i);
        else    insert(rx,x[i],i);
    }
    dfs(rx,0);
    for(i=1;i<=n;i++)    dfs(ry[i],i);
    for(i=1;i<=q;i++)    printf("%lld\n",ans[i]=ans[bel[i]]);
    return 0;

然額今年並木有考網路流。。。

華麗麗的Day1Day2雙炸

希望各位閱讀本blog的童鞋們努力學習,爭取Noip2018不辜負自己