T1:

求出前缀和,三维偏序O(nlog2n)CDQ

二维其实就可以

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1e6+,inf=;
int n,ans,tot,tree[*N];
long long a[N],b[N];
long long suma[N],sumb[N],c[*N];
struct node{
int ha,hb,id;
}s[N],d[N];
void add(int x,int k){
for(;x<=tot;x+=(x&-x))tree[x]=min(tree[x],k);
}
void clear(int x){
for(;x<=tot;x+=(x&-x))tree[x]=inf;
}
int ask(int x){
int num=inf;
for(;x;x-=(x&-x))num=min(tree[x],num);
return num;
}
void work(int l,int r){
if(l==r){
return;
}
int mid=(l+r)/;
work(l,mid),work(mid+,r);
int ll=l,rr=mid+,p=l;
while(ll<=mid&&rr<=r){
if(s[ll].ha<=s[rr].ha){
add(s[ll].hb,s[ll].id);
d[p++]=s[ll++];
}
else{
int x=ask(s[rr].hb);
if(x!=inf)ans=max(ans,s[rr].id-x);
d[p++]=s[rr++];
}
}
while(rr<=r){
int x=ask(s[rr].hb);
if(x!=inf)ans=max(ans,s[rr].id-x);
d[p++]=s[rr++];
}
for(int i=l;i<=ll;i++){
clear(s[i].hb);
}
while(ll<=mid)d[p++]=s[ll++];
for(int i=l;i<=r;i++)s[i]=d[i];
}
int main(){
// freopen("sequence.in","r",stdin);
scanf("%d",&n);
for(int i=;i<=n;i++){
scanf("%lld",&a[i]);
}
for(int i=;i<=n;i++){
scanf("%lld",&b[i]);
}
for(int i=;i<=n;i++){
if(i)suma[i]=suma[i-]+a[i];
if(i)sumb[i]=sumb[i-]+b[i];
c[++tot]=suma[i],c[++tot]=sumb[i];
}
sort(c+,c+tot+);
tot=unique(c+,c+tot+)-c-;
for(int i=;i<=tot;i++)tree[i]=inf;
for(int i=;i<=n;i++){
s[i].ha=lower_bound(c+,c+tot+,suma[i])-c;
s[i].hb=lower_bound(c+,c+tot+,sumb[i])-c;
s[i].id=i;
}
work(,n);
printf("%d\n",ans);
return ;
}

一开始没有处理0的位置,出题人慷慨地送了我90pts

T2:

区间DP+四边形不等式优化

DP合并方式是枚举决策点,左右可以看作独立的树,然后再整体加一层的贡献

发现决策点单调,于是f[i][j]只从p[i][j-1]->p[i+1][j]枚举决策点。p为决策点数组。

跳过四边形不等式证明:如果觉得决策点单调就把决策点矩阵打印出来,发现行列上均单调,则有可能可以四边形不等式优化。

O(n2

#include<iostream>
#include<cstdio>
using namespace std;
const long long inf=1e18;
int n,a[],p[][];
long long f[][],sum[];
int main()
{
// freopen("tree.in","r",stdin);
scanf("%d",&n);
for(int i=;i<=n;i++){
scanf("%d",&a[i]);
sum[i]=sum[i-]+a[i];
}
for(int i=;i<=n;i++){
for(int j=i;j<=n;j++){
f[i][j]=inf;
}
}
for(int i=;i<=n;i++)f[i][i]=a[i],p[i][i]=i;
for(int i=;i<=n;i++){
for(int j=;j+i-<=n;j++){
for(int k=p[j][j+i-];k<=p[j+][j+i-];k++){
if(f[j][k-]+f[k+][j+i-]+sum[j+i-]-sum[j-]<f[j][j+i-]){
f[j][j+i-]=f[j][k-]+f[k+][j+i-]+sum[j+i-]-sum[j-];
p[j][j+i-]=k;
}
}
}
}
printf("%lld\n",f[][n]);
return ;
}

T3:

设从k点开始转移,以1的最终值为答案。

列出转移方程:f[i]=∑f[j]/x+1,x为i的出度。移项,列出高斯消元数组。

对于一个点,当它作为k时,它的f值为0。又发现对于不同的k,每次其它点的消元式子并不会发生变化。

线段树分治,每次存下当前的数组,只消元一半,然后递归进下一层。当处理到只有一个点的区间时,这个点的答案即为消元数组中1号点对应的答案。

一开始避免了消元时的选行,以及消元的时候出现0似乎没有什么影响:

#include<iostream>
#include<cstdio>
using namespace std;
const int mod=;
int n,m;
int ver[],Next[],head[],tot,chu[];
long long val[][],ans[],d[][][];
void add(int x,int y){
ver[++tot]=y;
Next[tot]=head[x];
head[x]=tot;
}
long long ks(long long x,int k){
long long num=;
while(k){
if(k&)num=num*x%mod;
x=x*x%mod;
k>>=;
}
return num;
}
void make(int l,int r){
// int pos;
for(int i=l;i<=r;i++){
// pos=i;
// for(int j=i;j<=n;j++){
// if(val[j][i]>val[pos][i])pos=j;
// }
// for(int j=1;j<=n+1;j++){
// swap(val[i][j],val[pos][j]);
// }
int tmp=val[i][i];
if(!tmp)continue;
long long inv=ks(tmp,mod-);
for(int j=;j<=n+;j++){
val[i][j]=val[i][j]*inv%mod;
}
for(int j=;j<=n;j++){
if(j!=i){
int s=val[j][i];
for(int k=;k<=n+;k++){
val[j][k]=(val[j][k]-s*val[i][k]%mod+mod)%mod;
}
}
}
}
}
void work(int l,int r,int dep){
if(l==r){
ans[l]=val[][n+];
return;
}
// long long d[310][310];
for(int i=;i<=n;i++){
for(int j=;j<=n+;j++){
d[dep][i][j]=val[i][j];
}
}
int mid=(l+r)/;
make(l,mid);
work(mid+,r,dep+);
for(int i=;i<=n;i++){
for(int j=;j<=n+;j++){
val[i][j]=d[dep][i][j];
}
}
make(mid+,r);
work(l,mid,dep+);
}
int main()
{
// freopen("walk.in","r",stdin);
// freopen("1.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=,x,y;i<=m;i++){
scanf("%d%d",&x,&y);
add(x,y);
chu[x]++;
}
for(int i=;i<=n;i++){
val[i][i]=-chu[i];
// long long inv=ks(chu[i],mod-2);
for(int j=head[i];j;j=Next[j]){
int y=ver[j];
val[i][y]++;
}
val[i][n+]=-chu[i];
}
work(,n,);
for(int i=;i<=n;i++){
printf("%lld\n",ans[i]);
}
return ;
}

这样选行会错的原因是,对于一个k来说,整个消元过程中它是不能被选择到的。在它作为k的意义下,它的数组其实相当于不存在。

及时跳出选行即可:

#include<iostream>
#include<cstdio>
using namespace std;
const int mod=;
int n,m;
int ver[],Next[],head[],tot,chu[];
long long val[][],ans[],d[][][];
void add(int x,int y){
ver[++tot]=y;
Next[tot]=head[x];
head[x]=tot;
}
long long ks(long long x,int k){
long long num=;
while(k){
if(k&)num=num*x%mod;
x=x*x%mod;
k>>=;
}
return num;
}
void make(int l,int r){
int pos;
for(int i=l;i<=r;i++){
pos=i;
for(int j=i;j<=n;j++){
if(val[j][i]){pos=j;break;}
}
for(int j=;j<=n+;j++){
swap(val[i][j],val[pos][j]);
}
for(int j=;j<=n+;j++)val[i][j]=(val[i][j]+mod)%mod;
int tmp=val[i][i];
if(!tmp)continue;
long long inv=ks(tmp,mod-);
for(int j=;j<=n+;j++){
val[i][j]=val[i][j]*inv%mod;
}
for(int j=;j<=n;j++){
if(j!=i){
int s=val[j][i];
for(int k=;k<=n+;k++){
val[j][k]=(val[j][k]-s*val[i][k]%mod+mod)%mod;
}
}
}
}
}
void work(int l,int r,int dep){
if(l==r){
ans[l]=val[][n+];
return;
}
// long long d[310][310];
for(int i=;i<=n;i++){
for(int j=;j<=n+;j++){
d[dep][i][j]=val[i][j];
}
}
int mid=(l+r)/;
make(l,mid);
work(mid+,r,dep+);
for(int i=;i<=n;i++){
for(int j=;j<=n+;j++){
val[i][j]=d[dep][i][j];
}
}
make(mid+,r);
work(l,mid,dep+);
}
int main()
{
// freopen("walk.in","r",stdin);
// freopen("1.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=,x,y;i<=m;i++){
scanf("%d%d",&x,&y);
add(x,y);
chu[x]++;
}
for(int i=;i<=n;i++){
val[i][i]=-chu[i];
// long long inv=ks(chu[i],mod-2);
for(int j=head[i];j;j=Next[j]){
int y=ver[j];
val[i][y]++;
}
val[i][n+]=-chu[i];
}
work(,n,);
for(int i=;i<=n;i++){
printf("%lld\n",ans[i]);
}
return ;
}

↑上面的复杂度都是O(n3logn)每个点会被消log次,消一次是n2

//????????????????
//????????????
//exm??????
//??????????????? ?????????
#include<iostream>
#include<cstdio>
using namespace std;
const int mod=;
int n,m;
int ver[],Next[],head[],tot,chu[];
long long val[][],ans[],d[][][];
void add(int x,int y){
ver[++tot]=y;
Next[tot]=head[x];
head[x]=tot;
}
long long ks(long long x,int k){
long long num=;
while(k){
if(k&)num=num*x%mod;
x=x*x%mod;
k>>=;
}
return num;
}
void make(int l,int r,int L,int R){
for(int i=l;i<=r;i++){
// for(int j=1;j<=n+1;j++)val[i][j]=(val[i][j]+mod)%mod;
int tmp=val[i][i];
if(!tmp)continue;
long long inv=ks(tmp,mod-);
for(int j=L;j<=R;j++){
val[i][j]=val[i][j]*inv%mod;
}
val[i][n+]=val[i][n+]*inv%mod;
for(int j=;j<=n;j++){
if(j!=i){
int s=val[j][i];
if(!s)continue;
for(int k=L;k<=R;k++){
val[j][k]=(val[j][k]-s*val[i][k]%mod+mod)%mod;
}
val[j][n+]=(val[j][n+]-s*val[i][n+]%mod+mod)%mod;
}
}
}
}
void work(int l,int r,int dep){
if(l==r){
ans[l]=val[][n+];
return;
}
// long long d[310][310];
for(int i=;i<=n;i++){
for(int j=l;j<=r;j++){
d[dep][i][j]=val[i][j];
}
d[dep][i][n+]=val[i][n+];
}
int mid=(l+r)/;
make(l,mid,l,r);
work(mid+,r,dep+);
for(int i=;i<=n;i++){
for(int j=l;j<=r;j++){
val[i][j]=d[dep][i][j];
}
val[i][n+]=d[dep][i][n+];
}
make(mid+,r,l,r);
work(l,mid,dep+);
for(int i=;i<=n;i++){
for(int j=l;j<=r;j++){
val[i][j]=d[dep][i][j];
}
val[i][n+]=d[dep][i][n+];
}
}
int main()
{
// freopen("walk.in","r",stdin);
// freopen("1.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=,x,y;i<=m;i++){
scanf("%d%d",&x,&y);
add(x,y);
chu[x]++;
}
for(int i=;i<=n;i++){
val[i][i]=-chu[i];
// long long inv=ks(chu[i],mod-2);
for(int j=head[i];j;j=Next[j]){
int y=ver[j];
val[i][y]++;
}
val[i][n+]=-chu[i];
}
work(,n,);
for(int i=;i<=n;i++){
printf("%lld\n",ans[i]);
}
return ;
}

抄思路&&%%%巨神

↑这个是O(n3

为什么????陷入迷惑

2019.10.29 csp-s模拟测试93 反思总结的更多相关文章

  1. 2019.10.29 CSP%您赛第四场t2

    我太菜了我竟然不会分层图最短路 ____________________________________________________________________________________ ...

  2. 2019.8.3 [HZOI]NOIP模拟测试12 C. 分组

    2019.8.3 [HZOI]NOIP模拟测试12 C. 分组 全场比赛题解:https://pan.baidu.com/s/1eSAMuXk 刚看这题觉得很难,于是数据点分治 k只有1和2两种,分别 ...

  3. 2019.8.3 [HZOI]NOIP模拟测试12 B. 数颜色

    2019.8.3 [HZOI]NOIP模拟测试12 B. 数颜色 全场比赛题解:https://pan.baidu.com/s/1eSAMuXk 数据结构学傻的做法: 对每种颜色开动态开点线段树直接维 ...

  4. 2019.8.3 [HZOI]NOIP模拟测试12 A. 斐波那契(fibonacci)

    2019.8.3 [HZOI]NOIP模拟测试12 A. 斐波那契(fibonacci) 全场比赛题解:https://pan.baidu.com/s/1eSAMuXk 找规律 找两个节点的lca,需 ...

  5. csp-s模拟测试93

    csp-s模拟测试93 自闭场. $T1$想到$CDQ$,因为复杂度少看见一个$0$打了半年还用了$sort$直接废掉,$T2$,$T3$直接自闭暴力分都没有.考场太慌了,心态不好. 02:07:34 ...

  6. 2019.8.14 NOIP模拟测试21 反思总结

    模拟测试20的还没改完先咕着 各种细节问题=错失190pts T1大约三分钟搞出了式子,迅速码完,T2写了一半的时候怕最后被卡评测滚去交了,然后右端点没有初始化为n…但是这样还有80pts,而我后来还 ...

  7. 2019.8.9 NOIP模拟测试15 反思总结

    日常爆炸,考得一次比一次差XD 可能还是被身体拖慢了学习的进度吧,虽然按理来说没有影响.大家听的我也听过,大家学的我也没有缺勤多少次. 那么果然还是能力问题吗……? 虽然不愿意承认,但显然就是这样.对 ...

  8. 2019.8.1 NOIP模拟测试11 反思总结

    延迟了一天来补一个反思总结 急匆匆赶回来考试,我们这边大家的状态都稍微有一点差,不过最后的成绩总体来看好像还不错XD 其实这次拿分的大都是暴力[?],除了某些专注于某道题的人以及远程爆踩我们的某学车神 ...

  9. 2019.10.29 csp-s模拟测试92 反思总结

    今天快乐的墨雨笙因为什么而几乎爆零了呢? 顾此失彼+不会对拍+无脑的复杂度 今天高兴的墨雨笙又因为什么调了一个下午呢? 不明题意+不想范围+板子低级错误 R.I.P. T1: //唉 //害怕TLE, ...

随机推荐

  1. [kuangbin带你飞]专题一 简单搜索 - F - Prime Path

    #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #i ...

  2. ArrayList 和linkedList 插入比较

    从学Java开始, 就一直大脑记着  arrayList 底层是数组 ,查询快, 插入慢, 有移动的动作.linkedList 底层链表, 插入快 查询慢,今天写了例子跑了跑, 果然. public ...

  3. Object 和Throwable

    Object java.lang.Object 所有类的超类 Object里面有的方法所有的类都有 Object方法: String toString() 返回对象的字符串表现形式  类名 + @ + ...

  4. JS数组 二维数组 二维数组的表示 方法一: myarray[ ][ ];方法二:var Myarr = [[0 , 1 , 2 ],[1 , 2 , 3, ]]

    二维数组 一维数组,我们看成一组盒子,每个盒子只能放一个内容. 一维数组的表示: myarray[ ] 二维数组,我们看成一组盒子,不过每个盒子里还可以放多个盒子. 二维数组的表示: myarray[ ...

  5. bootstrap table 实现固定悬浮table 表头并可以水平滚动

    在开发项目中,需要将表格头部固定,而且表格大多数情况下是会水平滚动的.项目的css框架是bootstrap 3,故也可以叫做bootstrap table. 需要实现的是:表格头部固定,并且支持水平滚 ...

  6. 【BZOJ4407】于神之怒加强版

    题面 题目分析 \[ \begin{split} \sum\limits_{i=1}^n\sum\limits_{j=1}^mgcd(i,j)^k&=\sum\limits_{d=1}^nd^ ...

  7. [转]async & await 的前世今生(Updated)

    async 和 await 出现在C# 5.0之后,给并行编程带来了不少的方便,特别是当在MVC中的Action也变成async之后,有点开始什么都是async的味道了.但是这也给我们编程埋下了一些隐 ...

  8. Sentinel 发布里程碑版本,添加集群流控功能

    自去年10月底发布GA版本后,Sentinel在近期发布了另一个里程碑版本v1.4(最新的版本号是v1.4.1),加入了开发者关注的集群流控功能. 集群流控简介 为什么要使用集群流控呢?假设我们希望给 ...

  9. LUOGU P3355 骑士共存问题(二分图最大独立集)

    传送门 因为骑士只能走"日"字,所以一定是从一个奇点到偶点或偶点到奇点,那么这就是一张二分图,题目要求的其实就是二分图的最大独立集.最大独立集=n-最大匹配. #include&l ...

  10. 标准方程法_岭回归_LASSO算法_弹性网

    程序所用文件:https://files.cnblogs.com/files/henuliulei/%E5%9B%9E%E5%BD%92%E5%88%86%E7%B1%BB%E6%95%B0%E6%8 ...