我的微軟輸入法莫名其妙變成繁體了,你們有什麽頭緒嗎

狀態 題目
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的更多相关文章

  1. 计蒜客 NOIP 提高组模拟竞赛第一试 补记

    计蒜客 NOIP 提高组模拟竞赛第一试 补记 A. 广场车神 题目大意: 一个\(n\times m(n,m\le2000)\)的网格,初始时位于左下角的\((1,1)\)处,终点在右上角的\((n, ...

  2. JZOJ 5196. 【NOIP2017提高组模拟7.3】B

    5196. [NOIP2017提高组模拟7.3]B Time Limits: 1000 ms  Memory Limits: 262144 KB  Detailed Limits   Goto Pro ...

  3. JZOJ 5197. 【NOIP2017提高组模拟7.3】C

    5197. [NOIP2017提高组模拟7.3]C Time Limits: 1000 ms  Memory Limits: 262144 KB  Detailed Limits   Goto Pro ...

  4. JZOJ 5195. 【NOIP2017提高组模拟7.3】A

    5195. [NOIP2017提高组模拟7.3]A Time Limits: 1000 ms  Memory Limits: 262144 KB  Detailed Limits   Goto Pro ...

  5. JZOJ 5184. 【NOIP2017提高组模拟6.29】Gift

    5184. [NOIP2017提高组模拟6.29]Gift (Standard IO) Time Limits: 1000 ms  Memory Limits: 262144 KB  Detailed ...

  6. 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 ...

  7. ZROI提高组模拟赛05总结

    ZROI提高组模拟赛05总结 感觉是目前为止最简单的模拟赛了吧 但是依旧不尽人意... T1 有一半的人在30min前就A掉了 而我花了1h11min 就是一个简单的背包,我硬是转化了模型想了好久,生 ...

  8. NOIP2017提高组 模拟赛15(总结)

    NOIP2017提高组 模拟赛15(总结) 第一题 讨厌整除的小明 [题目描述] 小明作为一个数学迷,总会出于数字的一些性质喜欢上某个数字,然而当他喜欢数字k的时候,却十分讨厌那些能够整除k而比k小的 ...

  9. NOIP2017提高组 模拟赛13(总结)

    NOIP2017提高组 模拟赛13(总结) 第一题 函数 [题目描述] [输入格式] 三个整数. 1≤t<10^9+7,2≤l≤r≤5*10^6 [输出格式] 一个整数. [输出样例] 2 2 ...

  10. NOIP2017提高组模拟赛 10 (总结)

    NOIP2017提高组模拟赛 10 (总结) 第一题 机密信息 FJ有个很奇怪的习惯,他把他所有的机密信息都存放在一个叫机密盘的磁盘分区里,然而这个机密盘中却没有一个文件,那他是怎么存放信息呢?聪明的 ...

随机推荐

  1. 对比`Pinia `和` Vuex`,全面了解` Vue`状态管理

    Pinia和Vuex一样都是是vue的全局状态管理器.其实Pinia就是Vuex5,只不过为了尊重原作者的贡献就沿用了这个看起来很甜的名字Pinia. 本文将通过Vue3的形式对两者的不同实现方式进行 ...

  2. Django model层之执行原始SQL查询

    Django model层之执行原始SQL查询 by:授客 QQ:1033553122 测试环境 Win7 Django 1.11   执行原始SQL查询 Manager.raw(raw_query, ...

  3. c++ 异常记录

    vector的排序使用的iterator必须先+1 再-1,否则报溢出警告,不能正确排序遍历map获取到的是对象副本,需要引用,不能直接拿来做引用 fortmat只支持原始类型,wstring,str ...

  4. java中使用jdbc连接数据库操作

    先贴代码,在做说明 import java.sql.*; import java.util.ArrayList; import java.util.List; public class Conn { ...

  5. hive测试数据洗刷

    hive测试--HIVE数据分析 测试使用虚拟机中的hive 环境:虚拟机+jdk+hadoop+hive+mysql 题目: 1.数据导入:    要求将样表文件中的(sales_sample_20 ...

  6. 对比python学julia(第四章:人工智能)--(第一节)OpenCV编程初步(3)

    1.4.  人脸检测 (续上) 3.检测视频中的人脸 在VSCode环境中,新建一个空白源文件,以detect_video.jl作为文件名保存到项目文件夹中,然后编写程序检测视频流中的人脸(正脸).由 ...

  7. 【MongoDB】Re02 文档CRUD

    三.文档操作(行记录) 不管comment集合是否存在,直接在comment集合中创建一份文档 > db.comment.insert({"articleid":" ...

  8. 【H5】03 文本内容处理

    摘自: https://developer.mozilla.org/zh-CN/docs/Learn/HTML/Introduction_to_HTML/HTML_text_fundamentals ...

  9. 如何在vscode中同时运行多个文件——server/client模式——在launch.json文件中设置多个configurations再compounds

    在vscode中我们一般都是同一时间只运行一个代码,但是这种设置并不适合server/client模式,甚至有很多分布式和并行的项目需要同一时间运行多个client,针对这种情况我们可以通过设置vsc ...

  10. SonarQube集成Xunit单元测试

    安装SonarQube 利用docker 安装SonarQube docker run -d --name sonarqube -e SONAR_ES_BOOTSTRAP_CHECKS_DISABLE ...