点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f3f3f3f3f
#define N 600010
#define fir first
#define sec second
#define ll long long
//#define int long long
char buf[1<<21], *p1=buf, *p2=buf;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf, 1, 1<<21, stdin)), p1==p2?EOF:*p1++)
inline int read() {
int ans=0, f=1; char c=getchar();
while (!isdigit(c)) {if (c=='-') f=-f; c=getchar();}
while (isdigit(c)) {ans=(ans<<3)+(ans<<1)+(c^48); c=getchar();}
return ans*f;
}
int r, c, q, typ;
namespace task{
char op[10];
bool vis[N];
ll val[N], ans;
pair<ll, int> pos1[N], pos2[N];
int **id1, **id2, **down, **right, tot;
struct min_lct{
bool rev[N];
ll maxn[N], val[N];
int fa[N], maxi[N], id[N], son[N][2];
#define son(a, b) son[a][b]
#define loc(a) (son(fa[a], 1)==a)
#define isrot(a) (son(fa[a], 0)!=a&&son(fa[a], 1)!=a)
void pushup(int a) {
maxn[a]=max(val[a], max(maxn[son(a, 0)], maxn[son(a, 1)]));
maxi[a]=val[a]==maxn[a]?id[a]:(maxn[son(a, 0)]==maxn[a]?maxi[son(a, 0)]:maxi[son(a, 1)]);
}
void spread(int a) {
if (!rev[a]) return ;
if (son(a, 0)) swap(son(son(a, 0), 0), son(son(a, 0), 1)), rev[son(a, 0)]^=1;
if (son(a, 1)) swap(son(son(a, 1), 0), son(son(a, 1), 1)), rev[son(a, 1)]^=1;
rev[a]=0;
}
void ror(int x) {
int y=fa[x], z=fa[y], k=loc(x);
if (!isrot(y)) son(z, loc(y))=x; fa[x]=z;
son(y, k)=son(x, k^1); fa[son(x, k^1)]=y;
son(x, k^1)=y; fa[y]=x;
pushup(y); pushup(x);
}
void upd(int x) {if (!isrot(x)) upd(fa[x]); spread(x);}
void splay(int x) {
upd(x);
for (int f; f=fa[x],!isrot(x); ror(x))
if (!isrot(f)) loc(x)^loc(f)?ror(x):ror(f);
}
int access(int x) {
int lst;
for (lst=0; x; lst=x,x=fa[x])
splay(x), son(x, 1)=lst, pushup(x);
return lst;
}
void makerot(int x) {x=access(x); swap(son(x, 0), son(x, 1)); rev[x]^=1;}
int findrot(int x) {
x=access(x); spread(x);
while (son(x, 0)) x=son(x, 0), spread(x);
splay(x);
return x;
}
void split(int x, int y) {makerot(x); access(y); splay(y);}
void link(int x, int y) {/* cout<<"lct1::link "<<x<<' '<<y<<endl; */ makerot(x); splay(x); fa[x]=y;}
void cut(int x, int y) {split(x, y); fa[x]=son(y, 0)=0; pushup(y);}
pair<ll, int> qmax(int x, int y) {split(x, y); return {maxn[y], maxi[y]};}
void modify(int x, int w) {splay(x); val[x]=w; pushup(x);}
}lct1;
struct max_lct{
bool rev[N];
ll minn[N], val[N];
int fa[N], mini[N], id[N], son[N][2];
#define son(a, b) son[a][b]
#define loc(a) (son(fa[a], 1)==a)
#define isrot(a) (son(fa[a], 0)!=a&&son(fa[a], 1)!=a)
void pushup(int a) {
minn[a]=min(val[a], min(minn[son(a, 0)], minn[son(a, 1)]));
mini[a]=val[a]==minn[a]?id[a]:(minn[son(a, 0)]==minn[a]?mini[son(a, 0)]:mini[son(a, 1)]);
// cout<<"pushup: "<<a<<' ';
// cout<<"("<<minn[a]<<','<<mini[a]<<")"<<endl;
// cout<<"son ("<<son(a, 0)<<','<<son(a, 1)<<")"<<endl;
// cout<<"val: "<<val[a]<<' '<<id[a]<<endl;
}
void spread(int a) {
if (!rev[a]) return ;
if (son(a, 0)) swap(son(son(a, 0), 0), son(son(a, 0), 1)), rev[son(a, 0)]^=1;
if (son(a, 1)) swap(son(son(a, 1), 0), son(son(a, 1), 1)), rev[son(a, 1)]^=1;
rev[a]=0;
}
void ror(int x) {
int y=fa[x], z=fa[y], k=loc(x);
if (!isrot(y)) son(z, loc(y))=x; fa[x]=z;
son(y, k)=son(x, k^1); fa[son(x, k^1)]=y;
son(x, k^1)=y; fa[y]=x;
pushup(y); pushup(x);
}
void upd(int x) {if (!isrot(x)) upd(fa[x]); spread(x);}
void splay(int x) {
upd(x);
for (int f; f=fa[x],!isrot(x); ror(x))
if (!isrot(f)) loc(x)^loc(f)?ror(x):ror(f);
}
int access(int x) {
int lst;
for (lst=0; x; lst=x,x=fa[x])
splay(x), son(x, 1)=lst, pushup(x);
return lst;
}
void makerot(int x) {x=access(x); swap(son(x, 0), son(x, 1)); rev[x]^=1;}
int findrot(int x) {
x=access(x); spread(x);
while (son(x, 0)) x=son(x, 0), spread(x);
splay(x);
return x;
}
void split(int x, int y) {makerot(x); access(y); splay(y);}
void link(int x, int y) {/* cout<<"lct2::link "<<x<<' '<<y<<endl; */ makerot(x); splay(x); fa[x]=y;}
void cut(int x, int y) {split(x, y); fa[x]=son(y, 0)=0; pushup(y);}
pair<ll, int> qmin(int x, int y) {split(x, y); return {minn[y], mini[y]};}
void modify(int x, int w) {splay(x); val[x]=w; pushup(x);}
}lct2;
inline void decode(char ch, int &x, int &y, int &w, ll lstans) {
// R is 'r'
// C is 'c'
static int mask = 0xfffff;
w = (int) ((w ^ lstans) & mask);
if(ch == '-') x = (x + lstans - 1) % r + 1, y = (y + lstans - 1) % (c - 1) + 1;
if(ch == '|') x = (x + lstans - 1) % (r - 1) + 1, y = (y + lstans - 1) % c + 1;
}
void solve() {
id1=new int*[r+2]; id2=new int*[r+2]; down=new int*[r+2]; right=new int*[r+2];
for (int i=0; i<=r+1; ++i) id1[i]=new int[c+2], id2[i]=new int[c+2];
for (int i=0; i<=r+1; ++i) down[i]=new int[c+2], right[i]=new int[c+2];
for (int i=1; i<=r; ++i) for (int j=1; j<=c; ++j) lct1.val[id1[i][j]=++tot]=-INF, lct1.val[id1[i][j]]=-INF;
for (int i=1; i<r; ++i) for (int j=1; j<c; ++j) lct2.val[id2[i][j]=++tot]=INF, lct2.val[id2[i][j]]=INF;
for (int i=1; i<=r; ++i) for (int j=1; j<=c; ++j) {
if (i!=r) down[i][j]=++tot, lct1.maxi[tot]=lct2.mini[tot]=tot;
if (j!=c) right[i][j]=++tot, lct1.maxi[tot]=lct2.mini[tot]=tot;
}
lct1.maxn[0]=-INF, lct2.minn[0]=INF;
lct2.val[++tot]=INF; lct2.minn[tot]=INF;
for (int i=0; i<=r; ++i) id2[i][0]=id2[i][c]=tot;
for (int i=0; i<=c; ++i) id2[0][i]=id2[r][i]=tot;
for (int i=1; i<=r; ++i) for (int j=1; j<=c; ++j) {
if (i!=r) pos1[down[i][j]]={id1[i][j], id1[i+1][j]}, pos2[down[i][j]]={id2[i][j-1], id2[i][j]};
if (j!=c) pos1[right[i][j]]={id1[i][j], id1[i][j+1]}, pos2[right[i][j]]={id2[i-1][j], id2[i][j]};
}
for (int i=1; i<=tot; ++i) lct1.id[i]=i, lct2.id[i]=i;
// lct2.link(5, 9); lct2.link(9, 10);
// pair<int, int> t=lct2.qmin(5, 10);
// cout<<"qmin: "<<t.fir<<' '<<t.sec<<endl;
// exit(0);
for (int i=1; i<r; ++i) for (int j=1; j<=c; ++j) vis[down[i][j]]=1, lct1.link(id1[i][j], down[i][j]), lct1.link(down[i][j], id1[i+1][j]);
for (int i=1; i<c; ++i) vis[right[1][i]]=1, lct1.link(id1[1][i], right[1][i]), lct1.link(right[1][i], id1[1][i+1]);
for (int i=2; i<=r; ++i) for (int j=1; j<c; ++j) lct2.link(id2[i-1][j], right[i][j]), lct2.link(right[i][j], id2[i][j]);
// exit(0);
for (int i=1,x,y,w,now,lst; i<=q; ++i) {
// cout<<"i: "<<i<<endl;
scanf("%s%d%d%d", op, &x, &y, &w);
if (typ) decode(*op, x, y, w, ans);
if (*op=='-') {
// cout<<"case -"<<endl;
now=right[x][y];
lst=val[now]; lct1.modify(now, w), lct2.modify(now, w); val[now]=w;
if (vis[now]) {
// cout<<"in mst: "<<endl;
// cout<<id2[x-1][y]<<' '<<id2[x][y]<<endl;
pair<ll, int> t=lct2.qmin(id2[x-1][y], id2[x][y]);
// cout<<"t: "<<t.fir<<' '<<t.sec<<endl;
if (t.fir<val[now]) {
// cout<<"cause modify"<<endl;
lct1.cut(id1[x][y], now), lct1.cut(now, id1[x][y+1]);
lct1.link(pos1[t.sec].fir, t.sec), lct1.link(t.sec, pos1[t.sec].sec);
// cout<<"pos2: "<<pos2[t.sec].fir<<' '<<t.sec<<' '<<pos2[t.sec].sec<<endl;
lct2.cut(pos2[t.sec].fir, t.sec), lct2.cut(t.sec, pos2[t.sec].sec);
lct2.link(id2[x-1][y], now), lct2.link(now, id2[x][y]);
vis[now]^=1; vis[t.sec]^=1; ans=ans-lst+t.fir;
}
else ans=ans-lst+w;
}
else {
// cout<<"out mst"<<endl;
// cout<<"between: "<<id1[x][y]<<' '<<id1[x][y+1]<<endl;
pair<ll, int> t=lct1.qmax(id1[x][y], id1[x][y+1]);
// cout<<"t: "<<t.fir<<' '<<t.sec<<endl;
if (t.fir>val[now]) {
// cout<<"cause modify"<<endl;
lct2.cut(id2[x-1][y], now), lct2.cut(now, id2[x][y]);
lct2.link(pos2[t.sec].fir, t.sec), lct2.link(t.sec, pos2[t.sec].sec);
lct1.cut(pos1[t.sec].fir, t.sec), lct1.cut(t.sec, pos1[t.sec].sec);
lct1.link(id1[x][y], now), lct1.link(now, id1[x][y+1]);
vis[now]^=1; vis[t.sec]^=1; ans=ans-t.fir+w;
}
}
}
else {
// cout<<"case |"<<endl;
now=down[x][y];
// cout<<"now: "<<now<<endl;
lst=val[now]; lct1.modify(now, w), lct2.modify(now, w); val[now]=w;
if (vis[now]) {
// cout<<"in mst: "<<endl;
// cout<<"find: "<<id2[x][y-1]<<' '<<id2[x][y]<<endl;
pair<ll, int> t=lct2.qmin(id2[x][y-1], id2[x][y]);
// cout<<"t: "<<t.fir<<' '<<t.sec<<endl;
if (t.fir<val[now]) {
// cout<<"cause modify"<<endl;
lct1.cut(id1[x][y], now), lct1.cut(now, id1[x+1][y]);
lct1.link(pos1[t.sec].fir, t.sec), lct1.link(t.sec, pos1[t.sec].sec);
lct2.cut(pos2[t.sec].fir, t.sec), lct2.cut(t.sec, pos2[t.sec].sec);
lct2.link(id2[x][y-1], now), lct2.link(now, id2[x][y]);
vis[now]^=1; vis[t.sec]^=1; ans=ans-lst+t.fir;
}
else ans=ans-lst+w;
}
else {
// cout<<"out mst"<<endl;
pair<ll, int> t=lct1.qmax(id1[x][y], id1[x+1][y]);
if (t.fir>val[now]) {
// cout<<"cause modify"<<endl;
lct2.cut(id2[x][y-1], now), lct2.cut(now, id2[x][y]);
lct2.link(pos2[t.sec].fir, t.sec), lct2.link(t.sec, pos2[t.sec].sec);
lct1.cut(pos1[t.sec].fir, t.sec), lct1.cut(t.sec, pos1[t.sec].sec);
lct1.link(id1[x][y], now), lct1.link(now, id1[x+1][y]);
vis[now]^=1; vis[t.sec]^=1; ans=ans-t.fir+w;
}
}
}
printf("%lld\n", ans);
}
}
}
signed main()
{
freopen("channel.in", "r", stdin);
freopen("channel.out", "w", stdout);
scanf("%d%d%d%d", &typ, &r, &c, &q);
task::solve();
return 0;
}