妙啊
jzoj 6091 唐时月夜
https://jzoj.net/senior/#main/show/6091
因为下一次的操作一定会包含以前操作过的范围
如果我们倒着处理每个变换显然是可以得到最终答案的
矩阵竟然有个什么线性变换。
玄学
反正就是维护坐标的变换系数,一次变化就直接在系数上改就行了。
那个莫名其妙的取模直接用unsigned int就好啦
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#define LL unsigned int
using namespace std;
const int MAXN=4e3+5;
const int MAXM=2e5+5;
const LL mod=4294967296;
int num,n,m,q,op,l1,l2,r1,r2;
LL a,b,c,A[MAXN][MAXN],B[MAXN][MAXN],f[MAXN*MAXN],ans;
struct query{
int op,l1,l2,r1,r2;
}qry[MAXM];
struct node{
int x,y,l;
node(){x=y=l=0;}
node(int x,int y,int l):x(x),y(y),l(l){}
}X[MAXM],Y[MAXM];
void rev_1(node &a,node &b,int id){
int v=qry[id].l2+qry[id].r2;
a.l+=a.y*v,b.l+=b.y*v;
a.y*=-1,b.y*=-1;
}
void rev_2(node &a,node &b,int id){
int v=qry[id].l1+qry[id].r1;
a.l+=a.x*v,b.l+=b.x*v;
a.x*=-1,b.x*=-1;
}
void rev_3(node &a,node &b,int id){
int v=qry[id].l1-qry[id].l2;
a.l+=(a.x-a.y)*v,b.l+=(b.x-b.y)*v;
swap(a.x,a.y),swap(b.x,b.y);
}
void solve(){
node x=node(1,0,0),y=node(0,1,0);
for(int i=q;i>=1;i--){
if(qry[i].op==1) rev_1(x,y,i);
if(qry[i].op==2) rev_2(x,y,i);
if(qry[i].op==3) rev_3(x,y,i);
X[i]=x,Y[i]=y;
}
for(int id=1;id<=q;id++)
for(int i=qry[id].l1;i<=qry[id].r1;i++)for(int j=qry[id].l2;j<=qry[id].r2;j++)
if(id>1&&qry[id-1].l1<=i&&i<=qry[id-1].r1&&j==qry[id-1].l2) j=qry[id-1].r2;
else B[X[id].x*i+X[id].y*j+X[id].l][Y[id].x*i+Y[id].y*j+Y[id].l]=A[i][j];
}
int main(){
freopen("evernight.in","r",stdin);
freopen("evernight.out","w",stdout);
cin>>num>>n>>m>>q>>a>>b>>c;f[0]=c;
for(int i=1;i<=n*m;i++) f[i]=f[i-1]*a+b;
for(int i=1;i<=n;i++)for(int j=1;j<=m;j++) B[i][j]=A[i][j]=f[(i-1)*m+j];
for(int i=1;i<=q;i++) scanf("%d%d%d%d%d",&qry[i].op,&qry[i].l1,&qry[i].l2,&qry[i].r1,&qry[i].r2);
solve();
for(int i=1;i<=n;i++)for(int j=1;j<=m;j++) ans+=B[i][j]*f[(i-1)*m+j];
cout<<ans;
return 0;
}
jzoj 6092 附耳而至
https://jzoj.net/senior/#contest/show/2686/1
竟然又是网络流。
先极角排序+跑环找出所有的区域
变成对偶图(区域变成点,相邻有连边)
S向区域连光明值的边
区域向T连黑暗值的边
相邻的区域连代价的双向边
最小割表示不选的最小值
总和减去不选的就是答案
dinic要用当前弧优化
数组开小竟然是TLE,坑死我了
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int MAXN=4e4+5;
const int MAXM=2e5+5;
const int inf=1e9;
void read(int &x){
char c=getchar();
int f=1; x=0;
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
x*=f;
}
int num,n,m,cnt=1,S,T,ans;
struct point{
int x,y,a,b;
}p[MAXN];
struct edge{
int v,c;
double k;
edge(){v=c=k=0;}
edge(int u,int v,int c):v(v),c(c){k=atan2(p[v].y-p[u].y,p[v].x-p[u].x);}
bool operator <(edge a){return k<a.k;}
}e[MAXM*2];
vector<int>g[MAXN];
void add(int u,int v,int c){
e[++cnt]=edge(u,v,c),g[u].push_back(cnt);
e[++cnt]=edge(v,u,c),g[v].push_back(cnt);
}
bool comp(int a,int b){return e[a]<e[b];}
struct graph{
int head[MAXN*2],next[MAXN*10],to[MAXN*10],w[MAXN*10],cnt;
int d[MAXN*2],q[MAXN*2],h,t,cur[MAXN*2];
void init(){cnt=1;}
void add(int u,int v,int c){
next[++cnt]=head[u],to[cnt]=v,w[cnt]=c,head[u]=cnt;
next[++cnt]=head[v],to[cnt]=u,w[cnt]=0,head[v]=cnt;
}
bool bfs(){
memset(d,0,sizeof(d));
d[S]=1,h=t=0;q[t++]=S;
while(h<t){
int x=q[h++];
if(x==T) return 1;
for(int i=head[x];i;i=next[i]){
int y=to[i];
if(!d[y]&&w[i]) d[y]=d[x]+1,q[t++]=y;
}
}
return d[T];
}
int dfs(int x,int now){
if(x==T) return now;
int flow=0;
for(int &i=cur[x];i;i=next[i]){
int y=to[i];
if(d[y]==d[x]+1&&w[i]){
int can=dfs(y,min(now,w[i]));
now-=can,flow+=can;
w[i]-=can,w[i^1]+=can;
if(!now) break;
}
}
if(!flow) d[x]=-1;
return flow;
}
int dinic(){
int ans=0;
while(bfs()) memcpy(cur,head,sizeof(head)),ans+=dfs(S,inf);
return ans;
}
}G;
vector<int>::iterator it;
int next[MAXM*2],isv[MAXM*2],tot,bl[MAXM*2],val1[MAXM*2],val2[MAXM*2];
void build(){
for(int i=1;i<=n;i++) sort(g[i].begin(),g[i].end(),comp);
for(int i=2;i<=cnt;i++){
int v=e[i].v;
it=++lower_bound(g[v].begin(),g[v].end(),i^1,comp);
if(it==g[v].end()) it=g[v].begin();
next[i]=*it;
}
for(int i=2;i<=cnt;i++)if(!isv[i]){
tot++;
for(int j=i;!isv[j];j=next[j]) isv[j]=1,bl[j]=tot;
}
G.init();
for(int i=2,u,v,c;i<=cnt;i++){
u=bl[i],v=bl[i^1],c=e[i].c;
val1[u]+=p[e[i].v].a,val2[u]+=p[e[i].v].b;
if(u>v) continue;
G.add(u,v,c),G.add(v,u,c);
}
S=0,T=tot+1;
for(int i=1;i<=tot;i++) G.add(S,i,val1[i]),G.add(i,T,val2[i]);
}
int main(){
freopen("everfeel.in","r",stdin);
freopen("everfeel.out","w",stdout);
read(num),read(n),read(m);
for(int i=1;i<=n;i++) read(p[i].x),read(p[i].y),read(p[i].a),read(p[i].b);
for(int i=1,u,v,c;i<=m;i++) read(u),read(v),read(c),add(u,v,c);
build();
for(int i=1;i<=tot;i++) ans+=val1[i]+val2[i];
cout<<ans-G.dinic();
return 0;
}