暂无链接
欠钱
题目描述
南极的企鹅王国大学中生活着
只企鹅,作为
世纪的优秀大学生,企鹅们积极响应“大众创业,万众创新”的号召,纷纷创业。但是创业需要资金,企鹅们最近手头比较紧,只能互相借钱。
企鹅的借钱行为是有规律可循的:每只企鹅只会借一次钱,并且只会从一只企鹅那里借钱。借钱关系中不存在环(即不存在类似“金企鹅欠银企鹅钱,银企鹅欠铜企鹅钱,铜企鹅欠金企鹅钱”这种情况)。
企鹅的还钱行为也是有规律可循的:每只企鹅一旦新获得了一笔钱,就会立刻用这笔钱尽可能偿还自己欠的债务,直到债务偿清或用光这笔钱。它只会使用新获得的这笔钱,至于以前它有没有钱、有多少钱,与还钱行为无关。
企鹅们经常会做美梦。在一只企鹅
的梦里,它梦见自己创业成功,一下子获得了
元钱,于是(按照上文的还钱规则)它赶快把钱用来还债,接着拿到钱的那只企鹅也赶快把钱用来还债……如此往复,直到所有获得钱的企鹅都完成了还债操作。梦醒之后,它开心地把梦的内容告诉了另外一只企鹅
,企鹅
听了,也很开心,于是它问道:在你的梦里,我获得了多少钱呢? (指
去还债之前手里的钱,包括后来用于还债的钱和还债后
手里剩下的钱。 )
梦毕竟是梦,对实际的欠债情况没有影响。
格式
输入格式
第一行两个整数
和
,表示有
只企鹅,
个操作。
接下来
行,有两种可能的格式:
- :修改操作,企鹅 向企鹅 借了 元钱。
- :查询操作,询问假如 有了 元钱,企鹅 会净收入多少钱。
本题强制在线,也就是说:对于每个操作输入的变量 (如果没有 ,那就只有 )都不是实际的 ,想获得实际的 应当经过以下操作:
a = (a + lastans) % n + 1;
b = (b + lastans) % n + 1;
c = (c + lastans) % n + 1;
其中, 是上一次询问的答案。如果没有上一次询问, 为 。
输出格式
对每个询问操作,输出一行一个数表示答案。
样例
样例输入
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
数据范围
数据分为以下几种:
第一种:占
,
且
;
第二种:占
,所有借钱事件(
开头的操作)发生在所有询问事件(
开头的操作)之前;
第三种:占
,对于一只企鹅
,最多只有一只企鹅向
借钱;
第四种:占
,没有特殊性质,
大小有一定梯度。
对于所有数据,满足:
且
。
题解
考场上没看清题,以为是个 ,于是没去管,又被 毒瘤,最后没有时间写。。。
所以,你特么为什么要在 模拟赛 ,放一道 傻逼题呢???
我们只需要一棵维护链上最小值的有根 就能解决所有问题。
代码
#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();}