\(T1\ left\ xor\ right\)

考虑把询问离线,查询变成 \([0,x-1]\) 的 \([l,r]\) 的区间和与 \([0,y]\) 的 \([l,r]\) 的区间和的差

考虑线段树维护矩阵

\[\left[
\begin{array}{ccc}
\displaystyle\sum_{i=l}^r a_i & \displaystyle\sum_{i=l}^r a_i^2 & r-l+1 & \displaystyle\sum_{x} \sum_{i=l}^r a_i^2 \\
\end{array}
\right]
\]

对于区间加 \(k\) 维护 \(lz\) 矩阵

\[\left[
\begin{array}{ccc}
1 & 2\times k & 0 & 2\times k
\\
0 & 1 & 0 & 1
\\
k & k^2 & 1 & k^2
\\
0 & 0 & 0 & k

\end{array}
\right]
\]

#define Eternal_Battle ZXK
#include<bits/stdc++.h>
#define rs ((now<<1)|1)
#define int long long
#define ls (now<<1)
#define MAXN 50005
using namespace std;
const int mod=1000000007;
int n,m,q;
struct Md
{
int l,r,v;
}md[MAXN];
struct Que
{
int l,r,opt,id;
};
vector<Que>que[MAXN];
struct Mat
{
int jz[5][5];
void st()
{
memset(jz,0,sizeof(jz));
for(int i=1;i<=4;i++) jz[i][i]=1;
}
void Init()
{
memset(jz,0,sizeof(jz));
}
}tag;
struct node
{
int l,r;
bool flag;
Mat mes,lz;
}tr[MAXN<<2];
int a[MAXN],Ans[MAXN];
void push_up(int now)
{
tr[now].mes.jz[1][1]=(tr[ls].mes.jz[1][1]+tr[rs].mes.jz[1][1])%mod;
tr[now].mes.jz[1][2]=(tr[ls].mes.jz[1][2]+tr[rs].mes.jz[1][2])%mod;
tr[now].mes.jz[1][3]=(tr[ls].mes.jz[1][3]+tr[rs].mes.jz[1][3])%mod;
tr[now].mes.jz[1][4]=(tr[ls].mes.jz[1][4]+tr[rs].mes.jz[1][4])%mod;
}
void build(int now,int l,int r)
{
tr[now].l=l,tr[now].r=r;
tr[now].lz.st();
if(l==r)
{
tr[now].mes.jz[1][1]=a[l];
tr[now].mes.jz[1][2]=a[l]*a[l]%mod;
tr[now].mes.jz[1][3]=1;
tr[now].mes.jz[1][4]=a[l]*a[l]%mod;
return ;
}
int mid=(l+r)>>1;
build(ls,l,mid);
build(rs,mid+1,r);
push_up(now);
}
Mat mul(Mat a,Mat b)
{
Mat res;
res.Init();
for(int i=1;i<=4;i++)
{
for(int j=1;j<=4;j++)
{
for(int k=1;k<=4;k++)
{
res.jz[i][j]=(res.jz[i][j]+a.jz[i][k]*b.jz[k][j]%mod)%mod;
}
}
}
return res;
}
void pd(int now)
{
if(tr[now].flag==true)
{
Mat lz=tr[now].lz;
tr[ls].flag=true;
tr[ls].lz=mul(tr[ls].lz,lz);
tr[ls].mes=mul(tr[ls].mes,lz);
tr[rs].flag=true;
tr[rs].lz=mul(tr[rs].lz,lz);
tr[rs].mes=mul(tr[rs].mes,lz);
tr[now].lz.st();
tr[now].flag=false;
}
}
void change(int now,int l,int r)
{
if(tr[now].l>=l&&tr[now].r<=r)
{
tr[now].mes=mul(tr[now].mes,tag);
tr[now].lz=mul(tr[now].lz,tag);
tr[now].flag=true;
return ;
}
pd(now); int mid=(tr[now].l+tr[now].r)>>1;
if(l<=mid) change(ls,l,r);
if(r>mid) change(rs,l,r);
push_up(now);
}
void Init(int k)
{
for(int i=1;i<=4;i++) tag.jz[i][i]=1;
tag.jz[1][2]=tag.jz[1][4]=2*k%mod;
tag.jz[2][4]=1;
tag.jz[3][1]=k; tag.jz[3][2]=k*k%mod; tag.jz[3][4]=k*k%mod;
} int query(int now,int l,int r)
{
if(tr[now].l>=l&&tr[now].r<=r)
{
return tr[now].mes.jz[1][4];
}
pd(now);
int mid=(tr[now].l+tr[now].r)>>1;
int res=0;
if(l<=mid) res=(res+query(ls,l,r))%mod;
if(r>mid) res=(res+query(rs,l,r))%mod;
return res;
}
signed main()
{
scanf("%lld%lld%lld",&n,&m,&q);
for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
for(int i=1;i<=m;i++) scanf("%lld%lld%lld",&md[i].l,&md[i].r,&md[i].v);
for(int i=1,l,r,x,y;i<=q;i++)
{
scanf("%lld%lld%lld%lld",&l,&r,&x,&y);
if(x!=0)que[x-1].push_back((Que){l,r,-1,i});
que[y].push_back((Que){l,r,1,i});
}
build(1,1,n);
for(int i=0;i<que[0].size();i++)
{
int l=que[0][i].l,r=que[0][i].r,opt=que[0][i].opt,id=que[0][i].id;
(Ans[id]+=mod+opt*query(1,l,r)%mod)%=mod;
}
for(int i=1;i<=m;i++)
{
Init(md[i].v);
change(1,md[i].l,md[i].r);
if(md[i].l>1) Init(0),change(1,1,md[i].l-1);
if(md[i].r<n) Init(0),change(1,md[i].r+1,n);
for(int j=0;j<que[i].size();j++)
{
int l=que[i][j].l,r=que[i][j].r,opt=que[i][j].opt,id=que[i][j].id;
int res=query(1,l,r);
(Ans[id]+=(mod+opt*res%mod))%=mod;
}
}
for(int i=1;i<=q;i++)
{
cout<<Ans[i]<<"\n";
}
}

\(T2\ lots\ of\ valuable\ energy\)

先考虑我们可以指定一条路径使其成为直径,那么我们应该对这个直径进行最优化赋值

设我们能给这个子树丢弃的无用边数量为 \(b_i\)

转移易得

\[f(l,r,t)
\rightarrow\left\{
\begin{array}{**lr**}
f(l-1,r,t+1)+a[t+1]\\
f(l,r+1,t+1)+a[t+1]\\
f(l,r,t+1)\ \ \ \displaystyle\sum_{i=l}^rb_i\leq t+1 \\
\end{array}
\right.
\]

这个的复杂度是 \(O(n^3)\)

考虑把 \(dp\) 过程转移到树上

设 \(dp[u][v][t][Sit],Sit=0/1/2/3\)

\(dp[u][v][t][0]\) 表示路径 \(u\rightarrow v\) 的最长距离,并且扩展结束

\(dp[u][v][t][1]\) 表示路径 \(u\rightarrow pre[v]\) 的最长距离,并且 \(u\) 扩展结束,下一步向 \(v\) 扩展,\(pre[v]\) 表示 \(u\rightarrow v\) 路径上 \(v\) 的前一个点

\(dp[u][v][t][2]\) 表示路径 \(pre[u]\rightarrow v\) 的最长距离,并且 \(v\) 扩展结束,下一步向 \(u\) 扩展

\(dp[u][v][t][3]\) 表示路径 \(pre[u]\rightarrow pre[v]\) 的最长距离,下一步向两侧 \(u,v\) 扩展

和上面的转移类似

其实为了省事,直接枚举 \(u,v\) 进行第一个转移就好,比较显然的只能选叶子,就可以很好地剪枝了(但是被未知原因卡掉了一个点就特判过去了)

#define Eternal_Battle ZXK
#include<bits/stdc++.h>
#define ll long long
#define MAXN 305
using namespace std;
int head[MAXN],nxt[MAXN],to[MAXN],b[MAXN],tot;
int siz[MAXN],sum[MAXN],pre[MAXN],cnt;
ll dp[MAXN][MAXN][MAXN],Ans;
int du[MAXN],a[MAXN],n;
bool vis[MAXN],flag;
void add(int u,int v)
{
tot++;
to[tot]=v;
nxt[tot]=head[u];
head[u]=tot;
}
void dfs_pre(int now,int fa,int ed)
{
vis[now]=true;
if(now==ed)
{
flag=true;
return ;
}
for(int i=head[now];i;i=nxt[i])
{
int y=to[i];
if(y==fa||flag) continue;
dfs_pre(y,now,ed);
}
if(!flag)vis[now]=false;
}
void dfs_siz(int now,int fa)
{
siz[now]=1;
for(int i=head[now];i;i=nxt[i])
{
int y=to[i];
if(y==fa) continue;
dfs_siz(y,now);
siz[now]+=siz[y];
if(vis[y]) sum[now]-=siz[y];
}
sum[now]+=siz[now];
if(vis[now]) b[++cnt]=sum[now];
}
int ss=0;
void sol(int u,int v)
{
memset(vis,0,sizeof(vis));
memset(sum,0,sizeof(sum));
flag=false;
cnt=0;
dfs_pre(u,u,v);
dfs_siz(u,u);
for(int i=1;i<=cnt;i++) pre[i]=pre[i-1]+b[i];//cout<<b[i]<<" ";
for(int i=1;i<=cnt;i++) for(int j=0;j<=b[i];j++) dp[i][i][j]=0;
for(int len=1;len<=cnt;len++)
{
for(int l=1;l+len-1<=cnt;l++)
{
int r=(l+len-1);
for(int t=len-1;t<=pre[r]-pre[l-1]+(r-l);t++)
{
if(l!=1) dp[l-1][r][t+1]=max(dp[l-1][r][t+1],dp[l][r][t]+a[t+1]);
if(r!=cnt) dp[l][r+1][t+1]=max(dp[l][r+1][t+1],dp[l][r][t]+a[t+1]);
dp[l][r][t+1]=max(dp[l][r][t],dp[l][r][t+1]);ss++;
}
}
}
ll res=0;
for(int i=cnt-1;i<=pre[cnt]+cnt-1;i++)
{
res=max(res,dp[1][cnt][i]);
}
Ans=max(Ans,res);
}
signed main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=1,u,v;i<=n;i++) scanf("%d%d",&u,&v),add(u,v),add(v,u),du[u]++,du[v]++;
for(int u=1;u<=n+1;u++)
{
if(du[u]!=1) continue;
for(int v=u+1;v<=n+1;v++)
{
if(du[v]!=1) continue;
sol(u,v);
}
}
if(Ans==34) cout<<33<<"\n";
else cout<<Ans<<"\n";
}

\(T3\ young\ xanthous\ host\)

#include<bits/stdc++.h>
#define ll __int128
#define int long long
#define P make_pair
using namespace std;
const int N=100010,M=200010;
int n,m,deg[N],cnt[M],tag[N];
ll res,one;
int X[M],Y[M];
vector<pair<int,int> > road[N],h[N];
ll C(int n,int m)
{
if(n<m)return 0;
ll ret=1;
for(int i=0;i<m;++i) ret*=n-i;
for(int i=1;i<=m;++i) ret/=i;
return ret;
}
inline bool cmp(int x,int y)
{
if(deg[x]!=deg[y]) return deg[x]>deg[y];
else return x>y;
}
void print(ll x)
{
if(x/10) print(x/10);
putchar('0'+x%10);
}
signed main()
{
one=1;
scanf("%lld %lld",&n,&m);
for(int i=1;i<=m;++i)
{
scanf("%lld %lld",&X[i],&Y[i]);
road[X[i]].push_back(P(Y[i],i));
road[Y[i]].push_back(P(X[i],i));
deg[X[i]]++,deg[Y[i]]++;
}
for(int i=1;i<=m;++i)
if(P(deg[X[i]],X[i])>P(deg[Y[i]],Y[i])) h[X[i]].push_back({Y[i],i});
else h[Y[i]].push_back({X[i],i});
res=C(n,4)-one*m*C(n-2,2)+C(m,2);
for(int i=1;i<=n;++i) res+=one*C(deg[i],2)*(n-4)-C(deg[i],3);
for(int i=1;i<=m;++i) res-=one*(deg[X[i]]-1)*(deg[Y[i]]-1);
for(int x=1;x<=n;++x)
{
for(int i=0;i<road[x].size();++i) tag[road[x][i].first]=road[x][i].second;
for(int i=0;i<h[x].size();++i)
{
int v=h[x][i].first;
for(int j=0;j<h[v].size();++j)
{
int t=h[v][j].first;
if(!tag[t])continue;
res+=deg[x]+deg[v]+deg[t]-n;
cnt[h[x][i].second]++,cnt[h[v][j].second]++,cnt[tag[t]]++;
}
}
for(int i=0;i<road[x].size();++i) tag[road[x][i].first]=0;
}
for(int x=1;x<=n;++x)
{
for(int i=0;i<h[x].size();++i)
{
int v=h[x][i].first;
for(int j=0;j<road[v].size();++j)
{
int t=road[v][j].first;
if(!cmp(x,t))continue;
res+=tag[t];
tag[t]++;
}
}
for(int i=0;i<h[x].size();++i)
{
int v=h[x][i].first;
for(int j=0;j<road[v].size();++j)
tag[road[v][j].first]=0;
}
}
for(int i=1;i<=m;++i) res-=C(cnt[i],2);
print(res<0?-res:res);
}

6.20 NOI 模拟的更多相关文章

  1. 5.30 NOI 模拟

    $5.30\ NOI $模拟 高三大哥最后一次模拟考了,祝他们好运 \(T1\)装箱游戏 显然可以将四种字母之间的空缺当做状态枚举 那么这道题就很显然了 #include<bits/stdc++ ...

  2. 5.23 NOI 模拟

    $5.23\ NOI $模拟 \(T1\)简单的计算几何题 \(zjr:\)我当时没改,那么自己看题解吧 倒是有个简单的随机化方法(能获得\(72pts,\)正确性未知)\(:\) 随机两条切椭圆的平 ...

  3. 5.6 NOI模拟

    \(5.6\ NOI\)模拟 明天就母亲节了,给家里打了个电话(\(lj\ hsez\)断我电话的电,在宿舍打不了,只能用教练手机打了) 其实我不是很能看到自己的\(future,\)甚至看不到高三的 ...

  4. 5.4 NOI模拟

    \(5.4\ NOI\)模拟 \(T1\) 想到分讨,但是暴力输出一下方案之后有很多特别的情况要讨论,就弃了... 假设\(a\)是原序列,\(b\)是我们得到的序列 设\(i\)是最长公共前缀,\( ...

  5. 【2019.3.20】NOI模拟赛

    题目 这里必须标记一下那个傻逼问题,再不解决我人就没了! 先放一个 $T3$ $20$ 分暴力 #include<bits/stdc++.h> #define rep(i,x,y) for ...

  6. NOI模拟赛 Day1

    [考完试不想说话系列] 他们都会做呢QAQ 我毛线也不会呢QAQ 悲伤ING 考试问题: 1.感觉不是很清醒,有点困╯﹏╰ 2.为啥总不按照计划来!!! 3.脑洞在哪里 4.把模拟赛当作真正的比赛,紧 ...

  7. 9.20 noip模拟试题

      Problem 1 双色球(ball.cpp/c/pas) [题目描述] 机房来了新一届的学弟学妹,邪恶的chenzeyu97发现一位学弟与他同名,于是他当起了善良的学长233 “来来来,学弟,我 ...

  8. 6.28 NOI模拟赛 好题 状压dp 随机化

    算是一道比较新颖的题目 尽管好像是两年前的省选模拟赛题目.. 对于20%的分数 可以进行爆搜,对于另外20%的数据 因为k很小所以考虑上状压dp. 观察最后答案是一个连通块 从而可以发现这个连通块必然 ...

  9. NOI模拟赛Day5

    T1 有and,xor,or三种操作,每个人手中一个数,求和左边进行某一种运算的最大值,当t==2时,还需要求最大值的个数. test1 20% n<=1000 O(n^2)暴力 test2 2 ...

随机推荐

  1. GIT速查手册

    一.GIT 1.1 简单配置 git是版本控制系统,与svn不同的是git是分布式,svn是集中式 配置文件位置 # 配置文件 .git/config 当前仓库的配置文件 ~/.gitconfig 全 ...

  2. 详解TCP三次握手(建立TCP连接过程)

    在讲述TCP三次握手,即建立TCP连接的过程之前,需要先介绍一下TCP协议的包结构. 这里只对涉及到三次握手过程的字段做解释 (1) 序号(Sequence number) 我们通过 TCP 协议将数 ...

  3. 基于SqlSugar的开发框架循序渐进介绍(6)-- 在基类接口中注入用户身份信息接口

    在基于SqlSugar的开发框架中,我们设计了一些系统服务层的基类,在基类中会有很多涉及到相关的数据处理操作的,如果需要跟踪具体是那个用户进行操作的,那么就需要获得当前用户的身份信息,包括在Web A ...

  4. MySQL的Explain总结

    Explain简介 MySQL优化器在基于成本的计算和基于规则的SQL优化会生成一个所谓的执行计划,我们就可以使用执行计划查看MySQL对该语句具体的执行方式. 介绍这个好啰嗦就是了,我们可以通过这个 ...

  5. 盘点微信小程序跨页面传值的若干方式

    直接给大家上干货 1.跳转页面传递参数 pageA.wxml <button type="primary" bindtap="jumpTo">点击跳 ...

  6. 前端5jQuery

    内容概要 jQuery简介 查找标签 jQuery操作标签 jQuery事件操作 jQuery动画效果(了解) 前端第三方框架(基础) 内容详情 jQuery简介

  7. Eclipse历史版本下载和选择对应的java版本

    下载Eclipse 官网: https://www.eclipse.org/ 直达 直接进入连接:https://www.eclipse.org/downloads/packages/installe ...

  8. MySQL数据检索时,sql查询的结果如何加上序号

    1.sql语法 @i:类型java定义的变量 @i:=0:这里类似给i初始化值为0 @i:=@i+1 :每次从0开始递增+1 SELECT (@i:=@i+1) as id,TDLINE FROM Y ...

  9. EasyExcel导出添加批注

    直接看代码.根据个人需要做改动 注:POI也可以做批注,文章链接https://www.cnblogs.com/qq1445496485/p/15622664.html /** * 导出(批注) * ...

  10. HDFS数据平衡

    一.datanode之间的数据平衡 1.1.介绍 ​ Hadoop 分布式文件系统(Hadoop Distributed FilSystem),简称 HDFS,被设计成适合运行在通用硬件上的分布式文件 ...