来自FallDream的博客。未经允许,请勿转载,谢谢。

----------------------------------------------------

A.积分,不会  以后补

B.给定一个n*m的矩阵,每个点是0或者1,然后q个操作,每次把一个位置取反,然后询问最大的全是1的正方形的边长。n*m<=4000000 , q<=3900

题解:我们用一个线段树把所有行维护起来,然后每一行对每一列维护这个行区间的这一列的u和d,u表示从最下面一个最多有多少个连续的1,d表示从上面网下面最多有多少个连续的1,这两个参数是很好合并的。然后我们考虑计算过中线的答案。我们用两个指针ij,再用两个单调队列,维护u和d单调下降。每当 i - j + 1> u[tail] + d[tail] 的时候,我们把j指针往前移。最后我们用i - j + 1更新答案。

复杂度qmlogn  如果n<m我们把nm交换一下。

最近被奇怪的代码风格洗脑了,写了一个不像是我写的程序(听我解释,我真的不是抄的.....) 其实我真正的代码风格像C题那样就是一团垃圾

#include<iostream>
#include<cstdio>
#define MN 2000
#define TEST
using namespace std;
inline int read()
{
int x = , f = ; char ch = getchar();
while(ch < '' || ch > ''){ if(ch == '-') f = -; ch = getchar();}
while(ch >= '' && ch <= ''){x = x * + ch - '';ch = getchar();}
return x * f;
} inline int cread()
{
char ch = getchar();
while(ch != '.' && ch != 'X') ch = getchar();
return ch == '.' ? : ;
} int n , m , q , qx[MN + ] , ltop , qy[MN + ] , rtop , ltail , rtail;
bool *s[MN + ] , rev; struct Segment_Tree{
int ans , w;
int *u , *d;
Segment_Tree *l , *r;
void init(int x)
{
ans = ;
for(int i = ; i <= n ; ++i)
u[i] = d[i] = s[i][x] , ans |= s[i][x];
} void update()
{
ans = max ( l->ans , r->ans ); int x , k = ;
for(int i = ; i <= n ; ++i)
{
u[i] = l -> d[i];
d[i] = r -> u[i];
} qx[ltop = ] = qy[rtop = ] = ;
ltail = rtail = ; for ( int i = ; i <= n ; ++i)
{
while(u[i] <= u[qx[ltop]] && ltop >= ltail) ltop --;
while(d[i] <= d[qy[rtop]] && rtop >= rtail) rtop --; qx[++ ltop] = i;
qy[++ rtop] = i; while(i - k + > u[qx[ltail]] + d[qy[rtail]] && i > k)
{
++ k;
if(qx[ltail] < k) ltail ++;
if(qy[rtail] < k) rtail ++;
}
ans = max(ans , i - k + );
} for(int i = ; i <= n ; ++i)
{
u[i] = ( l -> u[i] == l -> w) ? r -> u[i] + l -> w : l -> u[i];
d[i] = ( r -> d[i] == r -> w) ? l -> d[i] + r -> w : r -> d[i];
}
} void modify(int x , int lt = , int rt = m)
{
if(lt == rt) { init(x); return;}
int mid = lt + rt >> ;
if(x <= mid) l -> modify(x , lt , mid);
else r -> modify(x , mid + , rt);
update();
} Segment_Tree(int lt , int rt )
{
u = new int [n + ];
d = new int [n + ];
w = rt - lt + ;
if(lt == rt) { init(lt); return;}
int mid = lt + rt >> ;
l = new Segment_Tree(lt , mid);
r = new Segment_Tree(mid + , rt);
update();
} }*rt; int main()
{
#ifdef TEST
freopen("s.in" , "r" , stdin);
freopen("s.out" , "w" , stdout);
#endif n = read(); m = read(); q = read();
if( n > m) swap(n , m),rev = true;
for(int i = ; i <= n ; ++i)
s[i] = new bool [m + ]; if(!rev)
for(int i = ; i <= n ; ++i)
for(int j = ; j <= m ; ++j)
s[i][j] = cread();
else
for(int i = ; i <= m ; ++i)
for(int j = ; j<= n ; ++j)
s[j][i] = cread(); rt = new Segment_Tree( , m); for(int i = ; i <= q ; ++i)
{
int x = read() , y = read();
if(rev) swap(x , y);
s[x][y] ^= ;
rt -> modify(y);
printf("%d\n" , rt -> ans);
}
return ;
}

C.给定一棵n个点树,每个点可以涂成白的或者黑的。给定b条链和b个权值bi,表示这条链上的点全是黑色时候能得到bi的贡献。还有a条链和a个权值,表示全部涂成白色能得到的贡献。你要求出最大贡献。n<=100000  a,b<=30000  3s

题解:神题

最小割,很显然黑白链就是一个二分图。但是直接建图是不行的,所以我们考虑优化一下,把树拿去树剖一下,然后建两棵线段树,一棵只能往下走,一棵只能往上走。每条链对两棵线段树上的对应的log个区间建边,最后跑一次最小割。复杂度很玄学,就算O(能过)吧。

ditoly真的强,居然在现场想出了这个做法...%%%

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define N 800000
#define MAXL 10000000
#define MV 860000
#define MAXN 100000
#define MN 100000
#define S 0
#define tt 860001
#define INF 2000000000
inline int read()
{
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-; ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-''; ch=getchar();}
return x*f;
}
int dn=,cnt=,ans=,n,B,W,head2[MAXN+],head[MV+],top[MAXN+],qx[MV+],qtop,tail;
int dfn[MAXN+],mx[MAXN+],size[MAXN+],dep[MAXN+],fa[MAXN+],q[MV+],tp[MV+];
struct edge{
int to,next,w;
}e[MAXL*+];
struct edge2{
int to,next;
}e2[MAXN*+];
struct TREE{
int l,r;
}T[MN*+]; inline void ins(int f,int t){e2[++cnt].next=head2[f];head2[f]=cnt;e2[cnt].to=t;}
inline void ins(int f,int t,int w){e[++cnt].next=head[f];head[f]=cnt;e[cnt].to=t;e[cnt].w=w;}
inline void insw(int f,int t,int w){ins(f,t,w);ins(t,f,);} void dfs(int x,int f)
{
size[x]=;mx[x]=;fa[x]=f;int maxn=;
for(int i=head2[x];i;i=e2[i].next)if(e2[i].to!=f)
{
dep[e2[i].to]=dep[x]+;dfs(e2[i].to,x);
size[x]+=size[e2[i].to];
if(size[e2[i].to]>maxn){maxn=size[e2[i].to];mx[x]=e2[i].to;}
}
} void dfs2(int x,int t)
{
top[x]=t;dfn[x]=++dn;
if(mx[x])dfs2(mx[x],t);
for(int i=head2[x];i;i=e2[i].next)if(!dfn[e2[i].to])
{dfs2(e2[i].to,e2[i].to);}
} void build(int x,int l,int r)
{
T[x].l=l;T[x].r=r;if(l==r)return;
int mid=(l+r)>>;
insw(x,x<<,INF);insw(x,x<<|,INF);
insw((x<<)+*MN,x+*MN,INF);insw((x<<|)+*MN,x+*MN,INF);
build(x<<,l,mid);build(x<<|,mid+,r);
} void insert(int from,int x,int l,int r)
{
// cout<<"insert"<<from<<" "<<x<<" "<<l<<" "<<r<<" "<<lt<<" "<<rt<<endl;
if(T[x].l==l&&T[x].r==r){insw(from,x,INF);insw(from,x+MN*,INF);return;}
int mid=(T[x].l+T[x].r)>>;
if(r<=mid)insert(from,x<<,l,r);
else if(l>mid)insert(from,x<<|,l,r);
else {insert(from,x<<,l,mid);insert(from,x<<|,mid+,r);}
} void insert2(int to,int x,int l,int r)
{
// cout<<"insert2"<<to<<" "<<x<<" "<<l<<" "<<r<<" "<<lt<<" "<<rt<<endl;
if(T[x].l==l&&T[x].r==r){insw(x,to,INF);insw(x+MN*,to,INF);return;}
int mid=(T[x].l+T[x].r)>>;
if(r<=mid)insert2(to,x<<,l,r);
else if(l>mid)insert2(to,x<<|,l,r);
else {insert2(to,x<<,l,mid);insert2(to,x<<|,mid+,r);}
} bool bfs()
{
memset(q,,sizeof(q));int i,j;
for(q[qx[qtop=i=]=S]=;i<=qtop;i++)
for(int j=tp[qx[i]]=head[qx[i]];j;j=e[j].next)if(!q[e[j].to]&&e[j].w)
q[qx[++qtop]=e[j].to]=q[qx[i]]+;
return q[tt]>;
} int solve(int x,int f)
{
// cout<<"solve"<<x<<" "<<f<<endl;
if(x==tt)return f;int used=;
for(int&i=tp[x];i;i=e[i].next)
if(e[i].w&&q[e[i].to]==q[x]+)
{
int w=solve(e[i].to,min(f-used,e[i].w));
used+=w;e[i].w-=w;e[i^].w+=w;
if(e[i].w) tp[x]=i;
if(used==f)return f;
}
if(!used)q[x]=-;
return used;
} int main()
{
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
n=read();B=read();W=read();
for(int i=;i<n;i++)
{int u=read(),v=read();ins(u,v),ins(v,u);}
cnt=;dfs(,);dfs2(,);
build(,,n);
for(int i=;i<=B;++i)
{
int u=read(),v=read(),x=read();insw(S,N+i,x);ans+=x;
while(top[u]!=top[v])
{
// cout<<u<<" "<<v<<" "<<top[u]<<" "<<top[v]<<endl;
if(dep[top[u]]>dep[top[v]])
{insert(N+i,,dfn[top[u]],dfn[u]);u=fa[top[u]];}
else
{insert(N+i,,dfn[top[v]],dfn[v]);v=fa[top[v]];}
}
if(dfn[u]>dfn[v])swap(u,v);insert(N+i,,dfn[u],dfn[v]);
}
for(int i=;i<=W;++i)
{
int u=read(),v=read(),x=read();insw(N+i+B,tt,x);ans+=x;
while(top[u]!=top[v])
{
// cout<<u<<" "<<v<<" "<<top[u]<<" "<<top[v]<<endl;
if(dep[top[u]]>dep[top[v]])
{insert2(N+i+B,,dfn[top[u]],dfn[u]);u=fa[top[u]];}
else
{insert2(N+i+B,,dfn[top[v]],dfn[v]);v=fa[top[v]];}
}
if(dfn[u]>dfn[v])swap(u,v);insert2(N+i+B,,dfn[u],dfn[v]);
}
while(bfs())ans-=solve(S,INF);
printf("%d\n",ans);
return ;
}

[3.19FJ四校联考]的更多相关文章

  1. [2017/5/28]FJ四校联考

    来自FallDream的博客,未经允许,请勿转载,谢谢. 话说这一段时间算是过去了,好久好久之后终于又有联考了  没想到这次到我们学校出题,昨天才想起来,临时花一天赶了一套,我出了一个sbFFT,质量 ...

  2. [四校联考P3] 区间颜色众数 (主席树)

    主席树 Description 给定一个长度为 N 颜色序列A,有M个询问:每次询问一个区间里是否有一种颜色的数量超过了区间的一半,并指出是哪种颜色. Input 输入文件第一行有两个整数:N和C 输 ...

  3. 四校联考 tree3

    我们考虑计算红色点与非红色点的对数. 我们用f[i][j]表示i的子树中有j个红色点的概率,将i所有子树合并. 接着我们对于每一个状态,枚举i是红色还是非红色算概率. 同时我们可以求出i和i子树内一个 ...

  4. 【四校联考】【比赛题解】FJ NOIP 四校联考 2017 Round 7

    此次比赛为厦门一中出题.都是聚劳,不敢恭维. 莫名爆了个0,究其原因,竟然是快读炸了……很狗,很难受. 话不多说,来看看题: [T1] 题意: 样例: PS:1<=h[i]<=100000 ...

  5. szoj461【四校联考0430】挑战

    传送门:(涉及版权忽略) [题解] 我们发现n的范围很小,提示我们可以折半,然后我们就会了O(T2^(n/2)*n)的做法,然而会T. 考虑如何优化.直接排序会多一个log(2^(n/2))也就是n, ...

  6. 三校联考 Day3

    三校联考 Day3 大水题 题目描述:给出一个圆及圆上的若干个点,问两个点间的最远距离. solution 按极角排序,按顺序枚举,显然距离最远的点是单调的,线性时间可解出答案. 大包子的束缚 题目描 ...

  7. 【赛时总结】NOIP2018-三校联考1024

    ◇NOIP三校联考-1024◇ 发现以前的博客写得似乎都很水……基本上都没什么阅读量QwQ 决定改过自新╰( ̄ω ̄o) 就从这篇博客开始吧~ 现场考得无地自容,看到题解才发现一些东西……(我第三题还没 ...

  8. [2019多校联考(Round 6 T3)]脱单计划 (费用流)

    [2019多校联考(Round 6 T3)]脱单计划 (费用流) 题面 你是一家相亲机构的策划总监,在一次相亲活动中,有 n 个小区的若干男士和 n个小区的若干女士报名了这次活动,你需要将这些参与者两 ...

  9. [多校联考2019(Round 5 T1)] [ATCoder3912]Xor Tree(状压dp)

    [多校联考2019(Round 5)] [ATCoder3912]Xor Tree(状压dp) 题面 给出一棵n个点的树,每条边有边权v,每次操作选中两个点,将这两个点之间的路径上的边权全部异或某个值 ...

随机推荐

  1. ajax的四种type类型

    1.GET请求会向数据库发索取数据的请求,从而来获取信息,该请求就像数据库的select操作一样,只是用来查询一下数据,不会修改.增加数据,不会影响资源的内容,即该请求不会产生副作用.无论进行多少次操 ...

  2. caffe实现GAN

    我实现GAN网络结构比较复杂: 通过建立两个一模一样的网络,他们相对应的层共享权重,一个网络用来跟新D model另一个网络用来更新G model 更新G model的网络,D部分只进行梯度传递,不进 ...

  3. 04_Linux目录文件操作命令1(mv ls cd...)_我的Linux之路

    上一节已经给大家讲了Linux的目录结构,相信大家已经对Linux的整个目录结构有所了解 现实中,服务器(包含Linux,Unix,windows server)一般都摆放在机房里,因为一个机房摆放了 ...

  4. javascript原型链__proto__属性的理解

    在javascript中,按照惯例,构造函数始终都应该以一个大写字母开头,而非构造函数则应该以一个小写字母开头.一个方法使用new操作符创建,例如下面代码块中的Person1(可以吧Person1看做 ...

  5. 电子称DIY(贴应变片+写代码)

    第一步.应变片介绍   ---------------------------------------------------------------------------------------- ...

  6. [翻译]现代java开发指南 第三部分

    现代java开发指南 第三部分 第三部分:Web开发 第一部分,第二部分,第三部分 =========================== 欢迎来到现代 Java 开发指南第三部分.在第一部分中,我们 ...

  7. Python-函数-Day4

    1.函数 1.1.集合 主要作用: 去重 关系测试, 交集\差集\并集\反向(对称)差集 a = {1,2,3,4} b ={3,4,5,6} a {1, 2, 3, 4} type(a) <c ...

  8. 搭建一个web服务下载HDFS的文件

    需求描述 为了能方便快速的获取HDFS中的文件,简单的搭建一个web服务提供下载很方便快速,而且在web服务器端不留临时文件,只做stream中转,效率相当高! 使用的框架是SpringMVC+HDF ...

  9. Oracle12c在Win10上的安装配置实践

    1.环境 操作系统:Win10专业版(64位) 数据库:Oracle 12c Release 2(Version 12.2.0.1.0,64位) 2.下载Oracle12c oracle官网下载地址: ...

  10. express学习(三)—— cookie和session

    express学习(三)-- cookie和session cookie存在浏览器中,最大只能保存4K数据,不安全 session存在服务器中,不能独立(先读取cookie再读取session),较安 ...