首页 > 其他分享 >Test 2022.09.26

Test 2022.09.26

时间:2022-09-26 21:36:58浏览次数:92  
标签:26 int tr long MAXN 2022.09 sup Test include

今天是水题专场

T1 扩散

感觉这种要么就是二分答案网络流,要么就是最小生成树,(随便口胡的),树德保留节目了属于是。

分析

简简单单一眼最小生成树(又是),边权就是两个点之间存在公共区域的时间,这个距离随便找一找规律就好算了。这里直接给结论了\(w(x1,y1,x2,y2)=\) \(\frac{abs(x1-x2)+abs(y1-y2)}{2}\)然后建所有可能的边,最后再最小生成树就行,(听说二分也能做?

Code

点击查看代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#define int long long
using namespace std;
const int maxn=100;
inline int read()
{
	int x=0,f=1;
	char c=getchar();
	while(c<'0'||c>'9')
	{
		if(c=='-')f=-1;
		c=getchar();
	}
	while('0'<=c&&c<='9')
	{
		x=(x<<1)+(x<<3)+(c^48);
		c=getchar();
	}
	return x*f;
}
int n;
int abs1(int x){return x>0?x:-x;}
int calc(int x1,int y1,int x2,int y2){return ceil((1.0*abs1(x1-x2)+1.0*abs1(y1-y2))/2);}
int x[maxn],y[maxn];
struct Edge{int u,v,w;}E[5000];int tote=0;
bool cmp(Edge a,Edge b){return a.w<b.w;}
int f[100];int find(int x){return x==f[x]?x:f[x]=find(f[x]);}
signed main()
{
	n=read();
	for(int i=1;i<=n;i++)x[i]=read(),y[i]=read(),f[i]=i;;
	for(int i=1;i<=n;i++)
		for(int j=i+1;j<=n;j++)
			E[++tote].u=i,E[tote].v=j,E[tote].w=calc(x[i],y[i],x[j],y[j]);
	sort(E+1,E+tote+1,cmp);
	int cnt=0;int ans=-1;
	for(int i=1;i<=tote;i++)
	{
		if(cnt==n-1)break;
		int x=find(E[i].u),y=find(E[i].v);
		if(x==y)continue;
		f[x]=y;
		ans=max(ans,E[i].w);
	}
	printf("%lld",ans);
	return 0;
}

T2 树链剖分板子

没有什么好说的,就浅浅地总结一下

\(dfs1\):求出基本信息:深度、父亲、子树大小、重儿子编号
\(dfs2\):求出\(dfn\)序、对应节点的权值、当前节点的重链顶端节点
\(query\):求出从\(l\)到\(r\)的路径上面的信息
实现方法就是只要当前两个节点的顶端节点不同,就让顶端节点深度更深的点跳到它所在重链的顶端,并且统计这一条链的答案,直到\(l、r\)在一条重链上面。最后再把深度深的点跳到浅的点上,再统计这一小节的答案。
画个图就很轻易地知道这时候每个子树的\(dfn\)序是一定连续的,所以就可以用线段树来维护区间最值

Code

点击查看代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#define int long long 
#define MAXN 200000
using namespace std;
inline int read()
{
    long long s=0,w=1;
    char ch=getchar();
    while(ch<'0'||ch>'9')
	{
  		if(ch=='-')w=-1;
		ch=getchar();
	}
    while(ch>='0'&&ch<='9')
    {
        s=(s<<3)+(s<<1)+(ch^48);
        ch=getchar();
    }
    return s*w;
} 
template <typename T>void wr(T x)
 {
	if(x<0) putchar('-'),x=-x;
	if(x>9) wr(x/10);
	putchar(x%10^'0');
	return;
}
int n,m;
long long val[MAXN];
struct Edge{int u,v;int nex;}tr[4*MAXN];
int head[MAXN],tote;
void add(int u,int v)
{
    tr[++tote].u=u;
    tr[tote].v=v;
    tr[tote].nex=head[u];
    head[u]=tote;
    tr[++tote].u=v;
    tr[tote].v=u;
    tr[tote].nex=head[v];
    head[v]=tote;
}
int fa[MAXN],siz[MAXN],dep[MAXN],son[MAXN];
void dfs1(int x,int f)
{
    dep[x]=dep[f]+1;siz[x]=1;fa[x]=f;
    int maxsonsize=-1;
    for(int i=head[x];i;i=tr[i].nex)
	{
        int v=tr[i].v;
        if(v==f)continue;
        dfs1(v,x);
        siz[x]+=siz[v];
        if(siz[v]>maxsonsize)maxsonsize=siz[v],son[x]=v;
    }
}
int id[MAXN],num;long long w[MAXN];int top[MAXN];
void dfs2(int x,int TOP)
{
    top[x]=TOP;id[x]=++num;w[id[x]]=val[x];
    if(!son[x])return;
    dfs2(son[x],TOP);
    for(int i=head[x];i;i=tr[i].nex)
	{
        int v=tr[i].v;
        if(v==fa[x]||v==son[x])continue;
        dfs2(v,v);
    }
}
struct Node{int l,r;long long val;long long tag;long long Max;}a[4*MAXN];
long long calc(int x){return a[x].val+(a[x].r-a[x].l+1)*a[x].tag;}
void down(int x)
{
    a[x<<1].tag+=a[x].tag;
    a[(x<<1)|1].tag+=a[x].tag;
    a[x].val=calc(x);
    a[x].tag=0;
    a[x].Max=max(a[x<<1].Max,a[(x<<1)|1].Max); 
}
void build(int x,int l,int r)
{
    a[x].l=l;a[x].r=r;
    if(l==r){a[x].val=a[x].Max=w[l];return;}
    int mid=(l+r)>>1;
    build(x<<1,l,mid);
    build((x<<1)|1,mid+1,r);
    a[x].val=calc(x<<1)+calc((x<<1)|1);
    a[x].Max=max(a[x<<1].Max,a[(x<<1)|1].Max);
}
void update(int x,int l,int r,int k)
{
    if(a[x].l>=l&&a[x].r<=r){a[x].tag+=k,a[x].Max=k;return;}
    down(x);
    int mid=(a[x].l+a[x].r)>>1;
    if(mid>=l)update(x<<1,l,r,k);
    if(mid<r)update((x<<1)|1,l,r,k);
    a[x].val=calc(x<<1)+calc((x<<1)+1);
    a[x].Max=max(a[x<<1].Max,a[(x<<1)|1].Max);
}
void change(int x,int pos,int v)
{
	if(a[x].l==a[x].r){a[x].val=v,a[x].Max=v;return;}
	int mid=(a[x].l+a[x].r)>>1;
	if(pos<=mid)change(x<<1,pos,v);
	else change(x<<1|1,pos,v);
	a[x].val=calc(x<<1)+calc(x<<1|1);
	a[x].Max=max(a[x<<1].Max,a[x<<1|1].Max);
}
long long query(int x,int l,int r)
{
    if(a[x].l>=l&&a[x].r<=r){return calc(x);}
    down(x);
    int mid=(a[x].l+a[x].r)>>1;
    long long ret=0;
    if(mid>=l)ret+=query(x<<1,l,r);
    if(mid<r)ret+=query((x<<1)|1,l,r);
    a[x].val=calc(x<<1)+calc((x<<1)|1);
    a[x].Max=max(a[x<<1].Max,a[(x<<1)|1].Max);
    return ret;
}
int querymax(int x,int l,int r)
{
	if(a[x].l>=l&&a[x].r<=r){return a[x].Max;}
	down(x);
    int mid=(a[x].l+a[x].r)>>1;int ans=-2147483640;
    if(mid>=l)ans=max(querymax(x<<1,l,r),ans);
    if(mid<r)ans=max(querymax((x<<1)|1,l,r),ans);
    return ans;
}
long long query_rootsum(int l,int r)
{
    long long ret=0;
    while(top[l]!=top[r])
	{
        if(dep[top[l]]<dep[top[r]])swap(l,r);
        ret+=query(1,id[top[l]],id[l]);
        l=fa[top[l]];
    }
    if(dep[l]>dep[r])swap(l,r);
    ret+=query(1,id[l],id[r]);
    return ret;
}
long long query_max(int l,int r)
{
	long long ans=-2147483640;
	while(top[l]!=top[r])
	{
		if(dep[top[l]]<dep[top[r]])swap(l,r);
		ans=max(querymax(1,id[top[l]],id[l]),ans);
		l=fa[top[l]];
	}
	if(dep[l]>dep[r])swap(l,r);
	ans=max(querymax(1,id[l],id[r]),ans);
	return ans;
}
string s;
signed main(){
    n=read();

    for(int i=1;i<n;i++)
	{
        int u,v;
        u=read(),v=read();
        add(u,v);
    }
    for(int i=1;i<=n;++i) val[i]=read();
    dfs1(1,0);
    dfs2(1,1);
    build(1,1,n);
    int q=read();
    for(int i=1;i<=q;i++)
	{
		cin>>s;
        if(s[0]=='C')
		{
            int x;
            long long y;
            x=read(),y=read();
            change(1,id[x],y);
        }
        else if(s=="QMAX")
        {
        	int x;long long y;
			x=read(),y=read();
			wr(query_max(x,y));        
        	printf("\n");
		}
        else if(s=="QSUM")
		{
            int x,y;
			x=read(),y=read();
			wr(query_rootsum(y,x));
            printf("\n");
        }
    }
    return 0;
}

T3佳佳的数学作业

一眼矩阵,可是一开始遇到了一些困难,比如转移矩阵里面必须是常值,但是后面经过一系列推导和转化,还是把感觉很妙的一个解给写出来了,马上就要去跑步了,推导的过程明早重点来写,先贴代码把

Code

点击查看代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define int long long
using namespace std;
const int maxn=1e5;
struct Matrix{int n,m,a[10][10];Matrix(){memset(a,0,sizeof a);};}sup[5];
int N,M;
Matrix operator *(Matrix a,Matrix b)
{
	Matrix tmp;tmp.n=a.n,tmp.m=b.m;
	for(int i=1;i<=a.n;i++)
		for(int j=1;j<=b.m;j++)
		{
			int c=0;
			for(int k=1;k<=a.m;k++)	c=(c%M+(a.a[i][k]%M)*(b.a[k][j]%M))%M;
			tmp.a[i][j]=c;
		}
	return tmp;
}
Matrix base(int x)
{
	Matrix tmp;tmp.n=tmp.m=x;
	for(int i=1;i<=x;i++)tmp.a[i][i]=1;
	return tmp;
}
Matrix Mpower(Matrix a,int b)
{
	Matrix ans=base(a.n);
	while(b)
	{
		if(b&1)ans=ans*a;
		a=a*a;
		b>>=1;
	}
	return ans;
}
void pre()
{
	sup[1].m=3,sup[1].n=3;
	sup[1].a[1][1]=1,sup[1].a[1][2]=1;
	sup[1].a[2][2]=1,sup[1].a[2][3]=1;
	sup[1].a[3][2]=1;
	sup[2].m=sup[2].n=5;
	sup[2].a[1][1]=1,sup[2].a[1][2]=1,sup[2].a[1][3]=-1;
	sup[2].a[2][2]=1;
	sup[2].a[3][3]=1;sup[2].a[3][4]=1;
	sup[2].a[4][4]=1,sup[2].a[4][5]=1;
	sup[2].a[5][4]=1;
}
void print(Matrix a)
{
	for(int i=1;i<=a.n;i++)
	{
		for(int j=1;j<=a.m;j++)
			printf("%lld ",a.a[i][j]);
		printf("\n");
	}
}
signed main()
{
	scanf("%lld%lld",&N,&M);
	pre();
	Matrix ans1;ans1.n=3,ans1.m=1;
	ans1.a[1][1]=0,ans1.a[2][1]=1,ans1.a[3][1]=0;
	ans1=Mpower(sup[1],N)*ans1;
	Matrix ans2;ans2.n=5,ans2.m=1;
	ans2.a[1][1]=0,ans2.a[2][1]=ans1.a[1][1],ans2.a[3][1]=0,ans2.a[4][1]=1,ans2.a[5][1]=0;
	ans2=Mpower(sup[2],N)*ans2;
	printf("%lld",(ans2.a[1][1]+M)%M);
	return 0;
}

T4中位数

说实话一开始真的没什么思路的,但是想到了对于当前这个位置统计它前后大于和小于它的是否相等,但实在没有想到用\(+1 -1\)的方式来表示,还可以用查分的方式来维护区间和

Code

点击查看代码
#include<iostream>
#include<cstdio>
#include<unordered_map>
#define ll long long
using namespace std;
int ans,wei,n,b,a[110000],tot,sum[110000];
unordered_map<int,int>mp;
int main(){
//	freopen("mid.in","r",stdin);
//	freopen("mid.out","w",stdout);
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin>>n>>b;
	for(register int i=1;i<=n;i++){
		cin>>a[i];
		if(a[i]==b)wei=i;
	}
	int big=0,small=0;
	for(register int i=wei;i>0;i--){
		if(a[i]>b)big++;
		else{
			if(a[i]<b)small++;
		}
		int delta=big-small;
		//if(delta==0)ans++;
		if(mp.find(delta)==mp.end()){
			mp[delta]=++tot;
		}
		sum[mp[delta]]++;
	}
	big=0;
	small=0;
	for(register int i=wei;i<=n;i++){
		if(a[i]>b)big++;
		else{
			if(a[i]<b)small++;
		}
		int delta=big-small;
		if(mp.find(-delta)==mp.end())continue;
		ans+=sum[mp[-delta]];
	}
	cout<<ans;
	return 0;
}
/*
7 4
5 7 2 4 3 1 6

9 5
9 8 1 2 5 4 3 6 7
*/

本来以为今天会很早就改完,没想到被树剖卡死了,害得多练啊

标签:26,int,tr,long,MAXN,2022.09,sup,Test,include
From: https://www.cnblogs.com/Hanggoash/p/16732557.html

相关文章

  • 9.26水题大赏
    2022-9-26T1扩散明显可以二分答案,也可以用最小生成树去做。考试时写的最小生成树,每两个点连一条边权为这两个点的曼哈顿距离。每次找最小的距离,\(\div2+1\)后更新\(ans......
  • 37th 2022/8/12 模拟赛总结26
    这次真不可理喻这次T1是差分约束,这次,得完全弄懂T1,因为之前考过差分约束,但一直都不会,改了题后却没有印象,这次做出总结:就是一个将输入改为一条形同松弛原理的式子,如:\(X_i-X......
  • 9.26-CSP-S模拟12
    T1开挂比较水的贪心题,可以证明一定只包含不相交,拿个栈就很好做了。点击查看代码#include<bits/stdc++.h>typedeflonglongll;typedefunsignedlonglongull;ty......
  • 2022.9.26比赛记录
    T1题意给定两个长度为\(n\)的序列\(a,b\),选择一个最长的区间\([l,r]\)使得\(\sum\limits_{i=l}^ra_i\ge0\)并且\(\sum\limits_{i=l}^rb_i\ge0\)。输出这个......
  • 9.26
    今日内容1.基本数据类型2.与用户交互3.格式化输出4.基本运算符5.常用赋值符6.逻辑运算符7.成员运算符8.身份运算符基本数据类型整型就是整数int代码实现:age......
  • ICPC2022 Online Contest 2 游记
    总结,8个题,前期罚时爆炸,后期坐牢。开局先找到签到题【E】。题意是给定\(a_1\)要求构造数组\(a_i\),满足\(\gcd(a_i,a_{i-1})==1\)且\(a_i>1\)。显然直接贪一波,......
  • 9月26日~10月2日
    9月26关于今天做了两道IOI的题,早些年的T1有些水……(虽然我做了IOI的题,但我却去不了IOI的赛场,艹好真实)。明白什么叫一步步来么......
  • 复制流报错:Latest checkpoint is at 2/7C3079A0 on timeline 1, but in the history o
    我的测试环境从PostgreSQL9.6.0异步复制流通过pg_upgrade方式升级到14.5,通过rsync将primary数据传输到standby端[postgres]]#rsync-avzpostgres@standby:/data/postgr......
  • 我的收藏周刊026
    文章分享“我觉得他们找错了靶子”许知远的《十三邀》之辩南方周末关于许知远十三邀的一篇文章,付费内容,值得一看。为什么需要虚拟化kernelnewbies上的以前为什么......
  • 闲话 22.9.26
    闲话调全体T4六点改出来了,但大样例不认为我改出来了于是又花了两个小时修改不存在的错误最近在做这题[JRKSJR4]risrqnis想做主要是因为上琴糖但是做着做着发现很......