CSP提高组模拟1
我的微軟輸入法莫名其妙變成繁體了,你們有什麽頭緒嗎
| 狀態 | 題目 |
|---|---|
| 20 Time Exceeded | A 最短路 |
| 25 Time Exceeded | B 方格取数 |
| 0 Time Exceeded | C 数组 |
| 70 Time Exceeded | D 树 |
A.最短路
我赛时想了想,会不会 DIJ 不是很对,因为这个题在打的时候觉得,在跑最短路的时候沿途加上点权有点草率了,但是后面没写完,所以也没回来想
有点像
我四十分的物理卷子
(内心):你做的这个对吗
我:管它呢,先画个圈,一会回来想,要不写不完了
(内心):你本来也写不完,要不再看看这题
(在想起一些不好的回忆(因为太磨叽挂了五十分)之后,还是毅然地跳了)
(过了一会)
(内心):跳了这么多,你这不也没写完
我:我草我前面还有题没想
所以这个题还是用 Floyed,为啥要点权从小到大排序,其实这么一听觉得真是太对了,但是我懒得想了,所以还是三遍 Floyed 来得实在(只需要保证完全更新就行了)
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int inf=0x3f3f3f3f3f3f3f3f;
int mp[301][301];
int dis[301][301];
int w[301];
int n,m,q;
void floyd(){
for(int k=1;k<=n;k++){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
int p=mp[i][k]+mp[k][j]+max(dis[i][k],dis[k][j]);
if((p<mp[i][j]+dis[i][j])&&mp[i][k]<inf&&mp[k][j]<inf){
mp[i][j]=mp[i][k]+mp[k][j];
dis[i][j]=max(dis[i][k],dis[k][j]);
}
}
}
}
}
signed main(){
freopen("path.in","r",stdin);
freopen("path.out","w",stdout);
cin>>n>>m>>q;
for(int i=1;i<=n;i++){
cin>>w[i];
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(i==j) mp[i][j]=0;
else mp[i][j]=inf;
}
}
for(int i=1;i<=m;i++){
int x,y,z;
cin>>x>>y>>z;
if(mp[x][y]>z){
mp[x][y]=z;
mp[y][x]=z;
dis[x][y]=max(w[x],w[y]);
dis[y][x]=max(w[x],w[y]);
}
}
floyd();floyd();floyd();
for(int i=1;i<=q;i++){
int x,y;
cin>>x>>y;
int res=mp[x][y]+dis[x][y];
cout<<(res>=0x3f3f3f3f3f3f3f3f?-1:res)<<endl;
}
}
B. 方格取数
这个题的 \(n^4\) 挺好想的,我因为没什么头绪打的也是 \(n^4\) 暴力,没想到还能拿点分
如果有一个点大于等于 \(k\) 且小于等于 \(2k\) ,那么我们直接输出这个点即可
如果有一个点大于 \(2k\) ,那么我们一定不可以选这个点,和包括它的矩形
那么现在这个矩阵上只剩下不能选的点和权值小于 \(k\) 的点了,否则跑不到这里就输出答案了.
因此我们现在在这个简化的矩阵上考虑答案
我们可以考虑先找出一个最大的矩阵,即使它的权值大于 \(2k\),在我们一点点减少的过程中,因为所有节点都小于 \(k\),一定会在 \([k,2k]\) 内出现一次,因此直接大力删就行了. 删下来以后(其实就是切开了)要判一下哪边比较大(或者直接合法了,那更好)
洛谷上过了,咱们题库上 \(n\) 和 \(k\) 居然是反的,答案坐标也是反的 ,题库上莫名其妙 T 了, \(40\) 分,懒得改了,这并不是 AC 代码
#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define N 2001
int k,n;
long long a[N][N];
long long sum[N][N];
int up[N][N],leftt[N],rightt[N];
long long ask(int lx,int ly,int ux,int uy){
return sum[ux][uy]-sum[lx-1][uy]-sum[ux][ly-1]+sum[lx-1][ly-1];
}
long long sumx;
int mat_sx,mat_sy,mat_ex,mat_ey;
void cutline(int x,int l,int r){
sumx=ask(x,l,x,r);
for(int i=r;i>=l;--i){
sumx-=a[x][i];
if(sumx>=k and sumx<=(k<<1)){
printf("%d %d %d %d",x,l,x,i-1);
exit(0);
}
}
}
void update(int lx,int ly,int ux,int uy){
long long t=ask(lx,ly,ux,uy);
if(t>=k and t<=(k<<1)){
printf("%d %d %d %d",lx,ly,ux,uy);
exit(0);
}
if(t>sumx){
sumx=t;
mat_sx=lx,mat_sy=ly,mat_ex=ux,mat_ey=uy;
}
}
stack<int>st;
signed main(){
freopen("matrix.in","r",stdin);
freopen("matrix.out","w",stdout);
cin>>n>>k;
for(int i=1;i<=n;++i){
for(int j=1;j<=n;++j){
cin>>a[i][j];
sum[i][j]=sum[i][j-1]+a[i][j];
if(a[i][j]>=k and a[i][j]<=(k<<1)){
printf("%d %d %d %d",i,j,i,j);
return 0;
}
}
for(int j=1;j<=n;++j){
sum[i][j]+=sum[i-1][j];
}
}
for(int i=1;i<=n;++i){
for(int j=1;j<=n;++j){
if(a[i][j]<k){
up[i][j]=up[i-1][j]+1;
}
}
while(!st.empty()) st.pop();
st.push(0);
up[i][0]=-1;
for(int j=1;j<=n;++j){
while(!st.empty() and up[i][st.top()]>=up[i][j]) st.pop();
leftt[j]=st.top()+1;
st.push(j);
}
while(!st.empty()) st.pop();
st.push(n+1);
up[i][n+1]=-1;
for(int j=n;j>=1;--j){
while(!st.empty() and up[i][st.top()]>=up[i][j]) st.pop();
rightt[j]=st.top()-1;
st.push(j);
if(up[i][j]) update(i-up[i][j]+1,leftt[j],i,rightt[j]);
}
}
if(sumx<k){
printf("-1\n");
return 0;
}
for(int i=mat_ex;i>=mat_sx;--i){
long long t=ask(i,mat_sy,i,mat_ey);
if(t>=k and t<=(k<<1)){
printf("%d %d %d %d",i,mat_sy,i,mat_ey);
return 0;
}
else if(t>(k<<1)){
cutline(i,mat_sy,mat_ey);
}
else{
sumx-=t;
if(sumx>=k and sumx<=(k<<1)){
printf("%d %d %d %d",mat_sx,mat_sy,i-1,mat_ey);
return 0;
}
}
}
}
C.数组
没想到搞了半天,线段树写对了,状压写对了,\(tag\) 写对了(其实是没写对,但是差不多对了),但是求 \(\phi\) 的时候寄了
这个题就是显然了,欧拉函数只要会求的就明白,直接根据积性函数(而且质因数也是差不多那种性质,所以极其好维护,取个或就行了)维护一下区间欧拉函数,扔到线段树里,拿出来的时候做个乘法就行了.
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int p=1000000007;
int power(int x,int t,int mod){
int ans=1,base=x;
while(t){
if(t&1){
ans=(ans*base)%mod;
}
base=base*base%mod;
t>>=1;
}
return ans;
}
struct tree{
int val;
int p;
int lazy,lazyP;
tree(){
val=1;
lazy=1;
p=0;
lazyP=0;
}
} t[1600001];
int n,q;
int a[1600001];
int f[1001],inv[1001];
int prime[]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293};
void update(int x){
t[x].val=t[x*2].val*t[x*2+1].val%p;
t[x].p=t[x*2].p|t[x*2+1].p;
}
void pushdown(int x,int l,int m,int r){
t[x*2].val=t[x*2].val*power(t[x].lazy,m-l+1,p)%p;
t[x*2+1].val=t[x*2+1].val*power(t[x].lazy,r-m,p)%p;
t[x*2].lazy=t[x*2].lazy*t[x].lazy%p;
t[x*2+1].lazy=t[x*2+1].lazy*t[x].lazy%p;
t[x*2].p|=t[x].lazyP;
t[x*2+1].p|=t[x].lazyP;
t[x*2].lazyP|=t[x].lazyP;
t[x*2+1].lazyP|=t[x].lazyP;
t[x].lazy=1;
t[x].lazyP=0;
}
void build(int l,int r,int x){
if(l==r){
t[x].val=a[l];
for(int i=0;i<62;++i){
if(a[l]%prime[i]==0){
t[x].p|=(1ll)<<i;
}
}
return;
}
int m=(l+r)/2;
build(l,m,x*2);
build(m+1,r,x*2+1);
update(x);
}
void update(int x,int l,int r,int delta,int prime,int cl,int cr){
if(cl>r or cr<l) return;
if(l<=cl and cr<=r){
t[x].val=t[x].val*power(delta,cr-cl+1,p)%p;
t[x].lazy=t[x].lazy*delta%p;
t[x].p|=prime;
t[x].lazyP|=prime;
return;
}
const int m=(cl+cr)/2;
pushdown(x,cl,m,cr);
update(x*2,l,r,delta,prime,cl,m);
update(x*2+1,l,r,delta,prime,m+1,cr);
update(x);
}
tree find(int x, int l, int r, int cl, int cr) {
if(cl>r or cr<l) return tree();
if(l<=cl and r>=cr) return t[x];
int m=(cl+cr)/2;
pushdown(x,cl,m,cr);
tree n;
tree ll=find(x*2,l,r,cl,m);
tree rr=find(x*2+1,l,r,m+1,cr);
n.val=ll.val*rr.val%p;
n.p=ll.p|rr.p;
return n;
}
signed main(){
freopen("array.in","r",stdin);
freopen("array.out","w",stdout);
cin>>n>>q;
for(int i=1;i<=n;++i){
cin>>a[i];
}
build(1,n,1);
inv[1]=1;
for(int i=2;i<=300;++i){
inv[i]=p-(p/i)*inv[p%i]%p;
}
for(int i=0;i<62;++i){
f[i]=inv[prime[i]]*(prime[i]-1)%p;
}
for(int i=1;i<=q;i++){
int opt,x,y;
cin>>opt>>x>>y;
if(opt==1){
int k;
cin>>k;
int t=0;
for(int i=0;i<62;++i){
if(k%prime[i]==0){
t|=(1ll)<<i;
}
}
update(1,x,y,k,t,1,n);
}
else{
tree ans=find(1,x,y,1,n);
int phi=ans.val;
for(int i=0;i<62;++i){
if(ans.p>>i&1){
phi=phi*f[i]%p;
}
}
cout<<phi%p<<endl;
}
}
}
D.树
懒得喷,谁造了组链的数据,还给那么大分
随机数据的话,考虑到先求个 Lca,然后两个节点都往 Lca 跳,每次都跳步长,一直到跳不动了,我们可以发现此时无论两个点位于哪里,中间一定不会再有其他点了.
因此倍增优化下 Lca,正好也能用来二进制优化跳步长,就能拿到这道题的大部分分.
啥比链,不写,感谢 luobotianle 提供的只过了链的假代码,拼上就行了
UPD: 原來链的不用根号分治也能过,这数据也太水了
#include<bits/stdc++.h>
using namespace std;
int n,w[50001];
vector<int>e[50001];
int fa[17][50001],deep[50001];
int xx[50001],yy[50001];
void dfs(int now,int last,int nowdeep){
fa[0][now]=last;
deep[now]=nowdeep;
for(int i:e[now]){
if(i!=last) dfs(i,now,nowdeep+1);
}
}
void prework(){
for(int i=1;i<=16;++i){
for(int j=1;j<=n;++j){
fa[i][j]=fa[i-1][fa[i-1][j]];
}
}
}
int jumpto(int x,int step){
int st=0;
while(step){
if(step&1){
x=fa[st][x];
}
step>>=1;
st++;
}
return x;
}
int lca(int x,int y){
if(deep[x]<deep[y]) swap(x,y);
for(int i=16;i>=0;--i){
// cout<<"deep "<<deep[x]<<" "<<deep[y]<<" "<<(1<<i)<<endl;
if(deep[x]-deep[y]>=(1<<i)){
// cout<<"jump "<<i<<endl;
x=fa[i][x];
}
}
for(int i=16;i>=0;--i){
if(fa[i][x]!=fa[i][y]){
x=fa[i][x];
y=fa[i][y];
}
}
// cout<<deep[x]<<" = "<<deep[y]<<endl;
// while(deep[x]!=deep[y]) x=fa[0][x];
// int cnt=0;
// while(x!=y){
// cnt++;
// x=fa[0][x],y=fa[0][y];
// }
// cout<<"jumpcnt "<<cnt<<endl;
// return x;
return x==y?x:fa[0][x];
}
int not_lca(int x,int y,int steplen){
int ans=w[x]+w[y],root=lca(x,y);
// cout<<"root "<<root<<endl;
// cout<<"++ "<<x<<" "<<y<<endl;
while(deep[x]-deep[root]>=steplen){
x=jumpto(x,steplen);
ans+=w[x];
// cout<<"+ "<<x<<endl;
}
while(deep[y]-deep[root]>=steplen){
y=jumpto(y,steplen);
// if(y!=root){
ans+=w[y];
// cout<<"+ "<<y<<endl;
// }
}
if(x==y) ans-=w[y];
return ans;
}
namespace lian{
const int N=5e4+5;
int a[N],b[N],c[N],x,y;
struct edge{
int next,to;
}e[N*2];
int h[N],cnt;
void add(int u,int v){
e[++cnt]={h[u],v};
h[u]=cnt;
}
int fa[N],top[N],son[N],dep[N],siz[N];
void dfs1(int x,int f){
fa[x]=f;
dep[x]=dep[f]+1;
siz[x]=1;
int maxc=0;
for(int i=h[x];i;i=e[i].next){
int to=e[i].to;
if(to==f)continue;
dfs1(to,x);
siz[x]+=siz[to];
if(siz[to]>maxc){
maxc=siz[to];
son[x]=to;
}
}
}
void dfs2(int x,int topf){
top[x]=topf;
if(!son[x])return;
dfs2(son[x],topf);
for(int i=h[x];i;i=e[i].next){
int to=e[i].to;
if(to==fa[x]||to==son[x])continue;
dfs2(to,to);
}
}
int lca(int x,int y){
while(top[x]!=top[y]){
// cout<<dep[top[x]]<<" "<<dep[top[y]]<<"\n";
if(dep[top[x]]<dep[top[y]])swap(x,y);
x=fa[top[x]];
}
return x;
}
void solve1(){
dfs2(1,1);dfs2(1,1);
for(int i=1;i<=n;i++)cin>>b[i];
for(int i=2;i<=n;i++)cin>>c[i];
for(int i=2;i<=n;i++){
int st=b[i-1],ed=b[i];
if(st>ed)swap(st,ed);
int ans=0;
for(int j=st;j<=ed;j+=c[i]){
ans+=a[j];
}
cout<<ans<<"\n";
}
}
int main(){
for(int i=1;i<=n;++i){
a[i]=w[i];
}
for(int i=1;i<n;i++){
add(xx[i],yy[i]);
add(yy[i],xx[i]);
}
solve1();
return 0;
dfs1(1,1);dfs2(1,1);
// for(int i=1;i<=n;i++){
// cout<<fa[i]<<" "<<dep[i]<<"\n";
// }
for(int i=1;i<=n;i++)cin>>b[i];
for(int i=2;i<=n;i++)cin>>c[i];
for(int i=2;i<=n;i++){
int st=b[i-1],ed=b[i];
int t=c[i];
int f=lca(st,ed);
int ans=0;
if(f==st||f==ed){
if(dep[st]<dep[ed])swap(st,ed);
ans=a[st];
while(st!=ed){
for(int j=1;j<=t;j++)st=fa[st];
ans+=a[st];
}
cout<<ans<<"\n";
}
else{
ans=a[st]+a[ed];
while(dep[st]-dep[f]>=t){
for(int j=1;j<=t;j++)st=fa[st];
ans+=a[st];
}
while(dep[ed]-dep[f]>=t){
for(int j=1;j<=t;j++)ed=fa[ed];
ans+=a[ed];
}
if(st==f&&ed==f)ans-=a[f];
cout<<ans<<"\n";
}
}
return 0;
}
}
int b[50001],c[50001];
int main(){
freopen("tree.in","r",stdin);
freopen("tree.out","w",stdout);
cin>>n;
for(int i=1;i<=n;++i){
cin>>w[i];
}
bool islian=true;
for(int i=1;i<=n-1;++i){
cin>>xx[i]>>yy[i];
if(abs(xx[i]-yy[i])!=1) islian=false;
e[xx[i]].push_back(yy[i]);
e[yy[i]].push_back(xx[i]);
}
if(islian){
lian::main();
}
else{
dfs(1,0,1);
prework();
for(int i=1;i<=n;++i){
cin>>b[i];
}
for(int i=1;i<=n-1;++i){
cin>>c[i];
}
for(int i=1;i<=n-1;++i){
cout<<not_lca(b[i],b[i+1],c[i])<<endl;
}
}
}
CSP提高组模拟1的更多相关文章
- 计蒜客 NOIP 提高组模拟竞赛第一试 补记
计蒜客 NOIP 提高组模拟竞赛第一试 补记 A. 广场车神 题目大意: 一个\(n\times m(n,m\le2000)\)的网格,初始时位于左下角的\((1,1)\)处,终点在右上角的\((n, ...
- JZOJ 5196. 【NOIP2017提高组模拟7.3】B
5196. [NOIP2017提高组模拟7.3]B Time Limits: 1000 ms Memory Limits: 262144 KB Detailed Limits Goto Pro ...
- JZOJ 5197. 【NOIP2017提高组模拟7.3】C
5197. [NOIP2017提高组模拟7.3]C Time Limits: 1000 ms Memory Limits: 262144 KB Detailed Limits Goto Pro ...
- JZOJ 5195. 【NOIP2017提高组模拟7.3】A
5195. [NOIP2017提高组模拟7.3]A Time Limits: 1000 ms Memory Limits: 262144 KB Detailed Limits Goto Pro ...
- JZOJ 5184. 【NOIP2017提高组模拟6.29】Gift
5184. [NOIP2017提高组模拟6.29]Gift (Standard IO) Time Limits: 1000 ms Memory Limits: 262144 KB Detailed ...
- JZOJ 5185. 【NOIP2017提高组模拟6.30】tty's sequence
5185. [NOIP2017提高组模拟6.30]tty's sequence (Standard IO) Time Limits: 1000 ms Memory Limits: 262144 KB ...
- ZROI提高组模拟赛05总结
ZROI提高组模拟赛05总结 感觉是目前为止最简单的模拟赛了吧 但是依旧不尽人意... T1 有一半的人在30min前就A掉了 而我花了1h11min 就是一个简单的背包,我硬是转化了模型想了好久,生 ...
- NOIP2017提高组 模拟赛15(总结)
NOIP2017提高组 模拟赛15(总结) 第一题 讨厌整除的小明 [题目描述] 小明作为一个数学迷,总会出于数字的一些性质喜欢上某个数字,然而当他喜欢数字k的时候,却十分讨厌那些能够整除k而比k小的 ...
- NOIP2017提高组 模拟赛13(总结)
NOIP2017提高组 模拟赛13(总结) 第一题 函数 [题目描述] [输入格式] 三个整数. 1≤t<10^9+7,2≤l≤r≤5*10^6 [输出格式] 一个整数. [输出样例] 2 2 ...
- NOIP2017提高组模拟赛 10 (总结)
NOIP2017提高组模拟赛 10 (总结) 第一题 机密信息 FJ有个很奇怪的习惯,他把他所有的机密信息都存放在一个叫机密盘的磁盘分区里,然而这个机密盘中却没有一个文件,那他是怎么存放信息呢?聪明的 ...
随机推荐
- 单细胞测序最好的教程(十六):关于RNA速率你想知道的都在这
作者按 本章节详细讲解了基于RNA速率的三种拟时序模型,包括稳态模型,EM模型和深度学习模型,并对比了不同模型的适用场景与计算特点.本教程首发于单细胞最好的中文教程,未经授权许可,禁止转载. 全文字数 ...
- 整段 html实现其中的每一个 a 标签跨域下载操作 window.URL.createObjectURL(blob)
window.URL.createObjectURL(blob) a 标签下载问题,通常在 a 标签中加上download属性,就可完成对href属性链接文件的下载,但仅仅是限于同源文件,如果是非同源 ...
- Nuxt.js 环境变量配置与使用
title: Nuxt.js 环境变量配置与使用 date: 2024/7/25 updated: 2024/7/25 author: cmdragon excerpt: 摘要:"该文探讨了 ...
- 【JavaScript】文件上传下载问题
问题原因 一般文件上传前端甚至可以不涉及JS来实现 input标签套在form标签,由form标签直接发送请求就可以实现上传功能 但是现在很多项目都使用前后端分离,AJAX一刀切所有. input标签 ...
- 怎么在Ubuntu系统云服务器搭建自己的幻兽帕鲁服务器?幻兽帕鲁搭建教程
<幻兽帕鲁>是一款备受瞩目的开放世界生存建造游戏,近期在游戏界非常火爆.玩家可以在游戏世界中收集神奇的生物"帕鲁",并利用它们进行战斗.建造.农耕.工业生产等各种活动. ...
- 为什么自动驾驶领域发论文都是用强化学习算法,但是实际公司里却没有一家使用强化学习算法?—— (特斯拉今年年初宣布推出实际上第一款纯端到端的自动驾驶系统,全部使用强化算法,替换掉30万行C++的rule-based代码)
为什么自动驾驶领域发论文都是用强化学习算法,但是实际公司里却没有一家使用强化学习算法?-- (特斯拉今年年初宣布推出实际上第一款纯端到端的自动驾驶系统,全部使用强化算法,替换掉原有的30万行C++的r ...
- php 开发日常收获
最近项目需求: 仿制某网站的菜单功能 效果如下: 效果大概就是这样啦.分析下吧:主要是分级查询我的思路:首先从数据库中查询所有的顶级目录: 目前就是这几个顶级目录在数据库中特点就是 父级id是0(一般 ...
- [POI2008] POC-Trains 题解
前言 题目链接:洛谷. 时间复杂度和输入同阶的做法. 题意简述 有 \(n\)(\(n \leq 10^3\))个长 \(m\) 的字符串,\(q\)(\(q \leq 10^5\))次操作,交换两个 ...
- 神经网络之卷积篇:详解更多边缘检测内容(More edge detection)
详解更多边缘检测内容 已经见识到用卷积运算实现垂直边缘检测,在本博客中,将看到如何区分正边和负边,这实际就是由亮到暗与由暗到亮的区别,也就是边缘的过渡.还能了解到其他类型的边缘检测以及如何去实现这些算 ...
- CryptoHouse:由 ClickHouse 和 Goldsky 支持的免费区块链分析服务(ClickHouse 博客)
我们很高兴地宣布 CryptoHouse,在 crypto.clickhouse.com 上可访问,这是一个由 ClickHouse 提供支持的免费区块链分析服务. https://crypto.cl ...
