[2018.10.11 T3] 欠钱

版权声明:大佬您能赏脸,蒟蒻倍感荣幸,还请联系我让我好好膜拜。 https://blog.csdn.net/ShadyPi/article/details/83048771

暂无链接

欠钱

题目描述

南极的企鹅王国大学中生活着 n n 只企鹅,作为 21 21 世纪的优秀大学生,企鹅们积极响应“大众创业,万众创新”的号召,纷纷创业。但是创业需要资金,企鹅们最近手头比较紧,只能互相借钱。
企鹅的借钱行为是有规律可循的:每只企鹅只会借一次钱,并且只会从一只企鹅那里借钱。借钱关系中不存在环(即不存在类似“金企鹅欠银企鹅钱,银企鹅欠铜企鹅钱,铜企鹅欠金企鹅钱”这种情况)。
企鹅的还钱行为也是有规律可循的:每只企鹅一旦新获得了一笔钱,就会立刻用这笔钱尽可能偿还自己欠的债务,直到债务偿清或用光这笔钱。它只会使用新获得的这笔钱,至于以前它有没有钱、有多少钱,与还钱行为无关。
企鹅们经常会做美梦。在一只企鹅 A A 的梦里,它梦见自己创业成功,一下子获得了 + +\infty 元钱,于是(按照上文的还钱规则)它赶快把钱用来还债,接着拿到钱的那只企鹅也赶快把钱用来还债……如此往复,直到所有获得钱的企鹅都完成了还债操作。梦醒之后,它开心地把梦的内容告诉了另外一只企鹅 B B ,企鹅 B B 听了,也很开心,于是它问道:在你的梦里,我获得了多少钱呢? (指 B B 去还债之前手里的钱,包括后来用于还债的钱和还债后 B B 手里剩下的钱。 )
梦毕竟是梦,对实际的欠债情况没有影响。

格式
输入格式

第一行两个整数 n n m m ,表示有 n n 只企鹅, m m 个操作。
接下来 m m 行,有两种可能的格式:

  • 0   a   b   c 0\ a\ b\ c :修改操作,企鹅 a a 向企鹅 b b 借了 c c 元钱。
  • 1   a   b 1\ a\ b :查询操作,询问假如 a a 有了 + 1 +1 元钱,企鹅 b b 会净收入多少钱。

本题强制在线,也就是说:对于每个操作输入的变量 a , b , c a,b,c (如果没有 c c ,那就只有 a , b a, b )都不是实际的 a , b , c a, b, c ,想获得实际的 a , b , c a, b, c 应当经过以下操作:

a = (a + lastans) % n + 1;
b = (b + lastans) % n + 1;
c = (c + lastans) % n + 1;

其中, l a s t a n s lastans 是上一次询问的答案。如果没有上一次询问, l a s t a n s lastans 0 0

输出格式

对每个询问操作,输出一行一个数表示答案。

样例
样例输入

5 9
0 1 2 1
0 0 1 2
1 0 1
1 2 4
0 2 1 1
1 2 0
0 3 1 0
1 4 2
1 3 4

样例输出

32010

数据范围

数据分为以下几种:
第一种:占 10 % 10\% n 5000 n ≤ 5000 m 10000 m ≤ 10000
第二种:占 20 % 20\% ,所有借钱事件( 0 0 开头的操作)发生在所有询问事件( 1 1 开头的操作)之前;
第三种:占 30 % 30\% ,对于一只企鹅 A A ,最多只有一只企鹅向 A A 借钱;
第四种:占 40 % 40\% ,没有特殊性质, n m n、 m 大小有一定梯度。
对于所有数据,满足: n 1 0 5 m 1 0 6 0 a , b , c n n ≤ 10^5, m ≤ 10^6, 0 ≤ a, b, c ≤ n a b a \neq b

题解

考场上没看清题,以为是个 D A G \mathcal{DAG} ,于是没去管,又被 T 1 \mathcal{T}1 毒瘤,最后没有时间写。。。

所以,你特么为什么要在 N O I P \mathcal{NOIP} 模拟赛 T 3 \mathcal{T}3 ,放一道 L C T \mathcal{LCT} 傻逼题呢???

我们只需要一棵维护链上最小值的有根 L C T \mathcal{LCT} 就能解决所有问题。

LCT.gif

代码
#include<bits/stdc++.h>
#define ls son[v][0]
#define rs son[v][1]
using namespace std;
const int M=2e5+5;
int son[M][2],dad[M],val[M],mn[M],n,m,tot;
bool notroot(int v){return son[dad[v]][0]==v||son[dad[v]][1]==v;}
void up(int v){mn[v]=min(val[v],min(mn[ls],mn[rs]));}
void spin(int v)
{
	int f=dad[v],ff=dad[f],k=son[f][1]==v,w=son[v][!k];
	if(notroot(f))son[ff][son[ff][1]==f]=v;son[v][!k]=f,son[f][k]=w;
	if(w)dad[w]=f;dad[f]=v,dad[v]=ff;
	up(f);
}
void splay(int v)
{
	for(int f,ff;notroot(v);spin(v))
	{
		f=dad[v],ff=dad[f];
		if(notroot(f))spin((son[f][0]==v)^(son[ff][0]==f)?v:f);
	}
	up(v);
}
int access(int v){int f=0;for(;v;v=dad[f=v])splay(v),rs=f,up(v);return f;}
void link(int x,int y){splay(x);dad[x]=y;}
void in(){scanf("%d%d",&n,&m);}
void ac()
{
	memset(val,127,sizeof(val));
	memset(mn,127,sizeof(mn));
	tot=n;
	for(int i=1,last=0,op,a,b,c;i<=m;++i)
	{
		scanf("%d%d%d",&op,&a,&b);
		a=(a+last)%n+1,b=(b+last)%n+1;
		if(op)access(b),(access(a)==b?(splay(b),printf("%d\n",last=min(val[b],mn[son[b][1]]))):(printf("%d\n",last=0)));
		else scanf("%d",&c),c=(c+last)%n+1,val[++tot]=c,mn[tot]=c,link(a,tot),link(tot,b);
	}
}
int main(){in(),ac();}

猜你喜欢

转载自blog.csdn.net/ShadyPi/article/details/83048771
T3