首页 > 其他分享 >2024暑假集训测试19

2024暑假集训测试19

时间:2024-08-09 15:21:12浏览次数:13  
标签:19 void mid Tp 2024 int read inline 集训

前言

image

T1 因为忘记判一个东西挂分,听说还有被卡哈希的,题目若按照难度正序的话应该是 T2、T1、T4、T3,T4 看到图论就比较胆怯没怎么想,T3 当然没想出来。

总而言之 T1 挂分的人挺多的,T2 都能做出来,T1 不挂分的排名都很靠前。

打得……不算很唐吧,除了 T1 挂分。

T1 串串

找回文中心,一个回文中心为合法的需满足一下条件之一:

  • 其回文右端点为 \(n\)。
  • 其回文左端点为 \(1\),且其右端点为合法回文中心。

由此从后往前扫一遍就行了,可以直接用哈希判回文,如果说回文中心是马拉车的专利话也可以用马拉车,二者复杂度单组数据均为 \(O(n)\),仔细想来直接暴力的复杂度似乎也能够过。

点击查看代码
#include<bits/stdc++.h>
#define ll long long 
#define endl '\n'
#define sort stable_sort
using namespace std;
const int N=1e6+10,P=998244353;
template<typename Tp> inline void read(Tp&x)
{
    x=0;register bool z=true;
    register char c=getchar();
    for(;c<'0'||c>'9';c=getchar()) if(c=='-') z=0;
    for(;'0'<=c&&c<='9';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
    x=(z?x:~x+1);
}
template<typename T,typename ...Tp> inline void read(T &x,Tp &...y){read(x);read(y...);}
template<typename Tp> inline void wt(Tp x)
{if(x>9)wt(x/10);putchar((x%10)+'0');}
template<typename Tp> inline void write(Tp x)
{if(x<0)putchar('-'),x=~x+1;wt(x);}
template<typename T,typename ...Tp> inline void write(T x,Tp ...y){write(x);putchar(' ');write(y...);}
int T;
char s[N];
ll h[2][N],b[N];
bool vis[N];
void init(int n)
{
    b[1]=1331;
    for(int i=2;i<=n;i++)
        b[i]=b[i-1]*b[1]%P;
}
void get_hash(char s[])
{
    int n=strlen(s);
    for(int i=0;i<=n-1;i++)
        h[0][i+1]=(h[0][i]*b[1]%P+s[i])%P;
    h[1][n+1]=0;
    for(int i=n-1;i>=0;i--)
        h[1][i+1]=(h[1][i+2]*b[1]%P+s[i])%P;
}
bool check(int l,int mid,int r)
{
    ll ans1=(h[0][mid]-h[0][l-1]*b[mid-l+1]%P+P)%P;
    ll ans2=(h[1][mid]-h[1][r+1]*b[r-mid+1]%P+P)%P;
    return ans1==ans2;
}
void solve(char s[])
{
    int n=strlen(s);
    vis[n]=1;
    for(int i=n-1;i>=2;i--)
    {
        if(check(i-(n-i),i,n)) vis[i]=1;
        else if(i+(i-1)<=n)
        {
            if(!vis[i+(i-1)]) continue;
            if(check(1,i,i+(i-1))) vis[i]=1;
        }
    }
    for(int i=1;i<=n;i++)
        if(vis[i])
        {
            write(i),putchar(' ');
            vis[i]=0;
        }
}
signed main()
{
    init(N-10);
    read(T);
    while(T--)
    {
        cin>>s;
        get_hash(s);
        solve(s);
        puts("");
    }
}

T2 排排

签到题,但由于放在了 T2 的位置且第一眼没有想到,比较晚才切。

答案只有 \(4\) 中情况:

  • \(0\):\(\forall a_i=i\)
  • \(1\):存在一个点满足 \(a_i=i\) 且满足 \(\forall j<i,a_j<a_i;\forall j>i,a_j>a_i\),因为其为一个排列,不会出现重复元素,所以直接记录前缀最大值即可,不需要开桶。
  • \(2\):发现若 \(1\) 在位置 \(1\) 上,下一步取 \(k=1\) 即可完成,所以此步在 \(1\) 的右面找一个 \(k\) 使得 \(1\) 回到位置 \(1\),下一步即可完成。\(n\) 同理。
  • \(3\):基于上面操作,若 \(a_1=n\) 且 \(a_n=1\),则需要先进行一步打破这个状态。
点击查看代码
#include<bits/stdc++.h>
#define ll long long 
#define endl '\n'
#define sort stable_sort
using namespace std;
const int N=2e5+10;
template<typename Tp> inline void read(Tp&x)
{
    x=0;register bool z=true;
    register char c=getchar();
    for(;c<'0'||c>'9';c=getchar()) if(c=='-') z=0;
    for(;'0'<=c&&c<='9';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
    x=(z?x:~x+1);
}
template<typename T,typename ...Tp> inline void read(T &x,Tp &...y){read(x);read(y...);}
template<typename Tp> inline void wt(Tp x)
{if(x>9)wt(x/10);putchar((x%10)+'0');}
template<typename Tp> inline void write(Tp x)
{if(x<0)putchar('-'),x=~x+1;wt(x);}
template<typename T,typename ...Tp> inline void write(T x,Tp ...y){write(x);putchar(' ');write(y...);}
int T,n,a[N];
signed main()
{
    read(T);
    while(T--)
    {
        read(n);
        for(int i=1;i<=n;i++) read(a[i]);
        bool flag=0;
        for(int i=1;i<=n;i++)
            if(a[i]!=i)
            {
                flag=1;
                break;
            }
        if(!flag)
        {
            puts("0");
            continue;
        }
        flag=0;
        int maxx=0;
        for(int i=1;i<=n;i++)
        {
            if(a[i]==i&&maxx<i)
            {
                puts("1");
                flag=1;
                break;
            }
            maxx=max(maxx,a[i]);
        }
        if(flag) continue;
        if(a[1]!=n||a[n]!=1)
        {
            puts("2");
            continue;
        }
        puts("3");
    }
}

T3 序序

  • 只有一组查询对应原题:P6406 [COCI2014-2015#2] Norma

  • 部分分 \(10pts\):\(O(n^2m)\) 暴力,这个卡卡常甚至能 \(20pts\)。

  • 部分分 \(20pts\):\(O(n^2)\) 二维前缀和预处理,\(O(1)\) 查询,空间复杂度也是 \(n^2\)。

  • 部分分 \(30pts\):在 \(20pts\) 的基础上序列递增的特殊性质用莫队冲过去。

  • 部分分 \(40pts\):对于单词查询复杂度为 \(O(n\log n)\) 分治,可过小数据点和只有一组查询的数据。

  • 部分分 \(50pts\):在 \(40pts\) 的基础上序列递增的特殊性质用莫队冲过去。

  • 正解没打出来。

单独写一下 \(40pts\) 的这个分治,对于 \([l,r]\) 依然是处理经过 \(mid\) 的贡献再递归 \([l,mid],[mid+1,r]\)。

从 \(mid\) 开始向左枚举左端点,此时有 \(min_l=\min\limits_{j=i}^{mid} a_j,max_l=\max\limits_{j=i}^{mid} a_j\),考虑其对 \([mid+1,r]\) 的贡献。

设 \(x\) 表示 \(min_l\) 在 \([mid+1,r]\) 中最远覆盖距离,\(y\) 表示 \(max_l\) 最远覆盖距离,不妨设 \(x<y\),有:

  • 在 \([mid+1,x]\) 这段区间内最大值为 \(max_l\),最小值为 \(min_l\),直接处理即可;
  • 在 \([x+1,y]\) 这段区间内最大值为 \(max_l\),最小值不为 \(min_l\);
  • 在 \([y+1,r]\) 这段区间内最大值不为 \(max_l\),最小值不为 \(min_l\)。

不放单独处理一个区间 \([mid+1,r]\) 的最大值、最小值、最大值乘最小值前缀和,三种情况分别处理,因为最小值单调不增,最大值单调不减,所以此做法是正确的。

点击查看代码
#include<bits/stdc++.h>
#define ll long long 
#define endl '\n'
#define sort stable_sort
using namespace std;
const int N=1e5+10,P=1e9+7;
template<typename Tp> inline void read(Tp&x)
{
    x=0;register bool z=true;
    register char c=getchar();
    for(;c<'0'||c>'9';c=getchar()) if(c=='-') z=0;
    for(;'0'<=c&&c<='9';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
    x=(z?x:~x+1);
}
template<typename T,typename ...Tp> inline void read(T &x,Tp &...y){read(x);read(y...);}
template<typename Tp> inline void wt(Tp x)
{if(x>9)wt(x/10);putchar((x%10)+'0');}
template<typename Tp> inline void write(Tp x)
{if(x<0)putchar('-'),x=~x+1;wt(x);}
template<typename T,typename ...Tp> inline void write(T x,Tp ...y){write(x);putchar(' ');write(y...);}
ll n,m,a[N],s1[N],s2[N],s3[N],ans;
void solve(int l,int r)
{
    if(l==r) 
    {
        (ans+=a[l]*a[l]%P)%=P;
        return ;
    }
    ll mid=(l+r)>>1,mi,mx,minn,maxx;
    mi=minn=0x3f3f3f3f,mx=maxx=0;
    s1[mid]=s2[mid]=s3[mid]=0;
    for(int i=mid+1;i<=r;i++)
    {
        minn=min(minn,a[i]),maxx=max(maxx,a[i]);
        s1[i]=(s1[i-1]+minn)%P;
        s2[i]=(s2[i-1]+maxx)%P;
        s3[i]=(s3[i-1]+minn*maxx%P)%P;
    }
    for(int i=mid,j=mid,k=mid;i>=l;i--)
    {
        mi=min(mi,a[i]),mx=max(mx,a[i]);
        for(;j<r&&a[j+1]>mi;j++);
        for(;k<r&&a[k+1]<mx;k++);
        int w1=min(j,k),w2=max(j,k);
        if(w1>mid)
            (ans+=mi*mx%P*(w1-mid)%P)%=P;
        if(k>w1)
            (ans+=mx*(s1[k]-s1[w1]+P)%P)%=P;
        if(j>w1)
            (ans+=mi*(s2[j]-s2[w1]+P)%P)%=P;
        (ans+=s3[r]-s3[w2]+P)%=P;
    }
    solve(l,mid),solve(mid+1,r);
}
signed main()
{
    read(n,m);
    for(int i=1;i<=n;i++) read(a[i]);
    for(int i=1,l,r;i<=m;i++)
    {
        read(l,r);
        ans=0;
        solve(l,r);
        write(ans),puts("");
    }
}

T4 桥桥

操作分块,每块单独处理,双指针从边权从大到小处理,加可撤销并查集维护,根据时间戳判定当前边权,全部操作完后暴力改掉所有边即可。

取快长为 \(\sqrt q\),每个块复杂度为 \(O(m\log m+q\log n)\),总复杂度约为 \(q\sqrt q\log m\)。

点击查看代码
#include<bits/stdc++.h>
#define ll long long 
#define endl '\n'
#define sort stable_sort
using namespace std;
const int N=1e5+10;
template<typename Tp> inline void read(Tp&x)
{
	x=0;register bool z=true;
	register char c=getchar();
	for(;c<'0'||c>'9';c=getchar()) if(c=='-') z=0;
	for(;'0'<=c&&c<='9';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
	x=(z?x:~x+1);
}
template<typename T,typename ...Tp> inline void read(T &x,Tp &...y){read(x);read(y...);}
template<typename Tp> inline void wt(Tp x)
{if(x>9)wt(x/10);putchar((x%10)+'0');}
template<typename Tp> inline void write(Tp x)
{if(x<0)putchar('-'),x=~x+1;wt(x);}
template<typename T,typename ...Tp> inline void write(T x,Tp ...y){write(x);putchar(' ');write(y...);}
int n,m,Q,t,pos[N],f[N],sz[N],vis[N],ans[N];
struct aa {int x,y,w,id;}e[N];
struct bb {int s,w,id;};
vector<bb>c,q,tmp;
stack<int>s1,s2;
bool cmp1(aa a,aa b) {return a.w>b.w;}
bool cmp2(bb a,bb b) {return a.w>b.w;}
int find(int x) {return f[x]==x?x:find(f[x]);}
void merge(int x,int y,stack<int> &s)
{
	x=find(x),y=find(y);
	if(x==y) return ;
	if(sz[x]<sz[y]) swap(x,y);
	s.push(y);
	sz[x]+=sz[y];
	f[y]=x;
}
void split(stack<int> &s)
{
	while(!s.empty())
	{
		sz[f[s.top()]]-=sz[s.top()];
		f[s.top()]=s.top();
		s.pop();
	}
}
void solve()
{
	sort(e+1,e+1+m,cmp1);
	sort(q.begin(),q.end(),cmp2);
	for(int i=1;i<=m;i++) pos[e[i].id]=i;
	for(int i=1;i<=n;i++) f[i]=i,sz[i]=1;
	tmp.clear();
	for(auto y:c)
	{
		vis[y.s]=-1;
		tmp.push_back({y.s,e[pos[y.s]].w,0});
	}
	for(auto y:c) 
		tmp.push_back({y.s,y.w,y.id});
	while(!s1.empty()) s1.pop();
	for(int i=0,j=1;i<q.size();i++)
	{
		for(;e[j].w>=q[i].w&&j<=m;j++)
			if(vis[e[j].id]==0) merge(e[j].x,e[j].y,s1);
		for(auto y:tmp)
			if(y.id<=q[i].id) vis[y.s]=y.w;
		for(auto y:c)
			if(vis[y.s]>=q[i].w) merge(e[pos[y.s]].x,e[pos[y.s]].y,s2);
		ans[q[i].id]=sz[find(q[i].s)];
		split(s2);
	}
	for(auto y:c) 
	{
		e[pos[y.s]].w=y.w;
		vis[y.s]=0;
	}
	c.clear(),q.clear();
}
signed main()
{
	read(n,m);
	t=1075;
	for(int i=1,x,y,z;i<=m;i++)
	{
		read(x,y,z);
		e[i]={x,y,z,i};
	}
	read(Q);
	for(int i=1,op,x,y;i<=Q;i++)
	{
		read(op,x,y);
		if(op==1) c.push_back({x,y,i});
		else q.push_back({x,y,i});
		if(i%t==0) solve();
	}
	if(Q%t!=0) solve();
	for(int i=1;i<=Q;i++) 
		if(ans[i]!=0) write(ans[i]),puts("");
}

总结

注意一些细节,避免像 T1 一样挂分。

附录

其实是前天打的,今天才补上。

标签:19,void,mid,Tp,2024,int,read,inline,集训
From: https://www.cnblogs.com/Charlieljk/p/18347923

相关文章

  • 2024.8 #5 午夜时分月上枝头 谁为谁心疼 一杯浊酒浇在心头 谁让谁心冷
    午夜时分月上枝头谁为谁心疼一杯浊酒浇在心头谁让谁心冷----洛天依《广寒宫》1.ChoosingAds考虑最简单的情况,即\(p>50\)。那么这个问题就是请问出现次数\(>\dfrac{n}{2}\)的数。Lemma:我们每次随机删除不相等的两个数,那么留下来的那个(那些)数就是答案。Proof:假如......
  • 福昕高级PDF编辑器专业版 v2024 激活版
    福昕高级PDF编辑器是一款功能强大的PDF文件编辑软件,提供多种实用的编辑功能。软件功能:PDF文档编辑:用户可编辑PDF文档内容,包括文字、图片、表格、图形等,且不会对原有文本内容造成影响。批注工具:提供多种批注工具,如注释,连线框和浮动注释,在PDF文件中添加批注和标记以便于阅读。......
  • C语言试题汇编 答案 9.192&9.193
    9.192有4名学生,每个学生考4门课程,要求在用户输入学生序号以后能输出该学生的全部成绩,用指针型函数实现。#include<stdio.h>float*search(float(*pointer)[4],intn);intmain(){ staticfloatscore[][4]={{60,70,80,90},{50,89,67,88},{34,78,67,88},{80,90,100,70}}; ......
  • [十二省联考 2019] 异或粽子
    如果这道题目会可持久化trie的话,是可以用“超级钢琴”这一道题目的思路去做的如果不行的话,考虑用trie,然后这篇题解关于trie的常用trick的综合可以记住讲一下怎么查找第\(k\)大,不要用二分了,直接把\(sum_r\)放在trie树上查找。trie树每个点记录一下这个点的子树有多少个位置(这个维......
  • 【11月杭州,邀您投稿参会】2024年计算机视觉与图像处理国际学术会议 (CVIP 2024)
    【重要信息】会议官网:iccvip.org大会时间:2024年11月15日-17日大会地点:中国杭州一轮截稿日期:2024年8月21日接受/拒稿通知:投稿后1周内收录检索:EICompendex,Scopus【大会简介】2024年计算机视觉与图像处理国际学术会议(CVIP2024)将于2024年11月15日-17日在中国杭州举......
  • 福昕高级PDF编辑器专业版 v2024 激活版
    福昕高级PDF编辑器是一款功能强大的PDF文件编辑软件,提供多种实用的编辑功能。软件功能:PDF文档编辑:用户可编辑PDF文档内容,包括文字、图片、表格、图形等,且不会对原有文本内容造成影响。批注工具:提供多种批注工具,如注释,连线框和浮动注释,在PDF文件中添加批注和标记以便于阅读。......
  • 福昕高级PDF编辑器专业版 v2024 激活版
    福昕高级PDF编辑器是一款功能强大的PDF文件编辑软件,提供多种实用的编辑功能。软件功能:PDF文档编辑:用户可编辑PDF文档内容,包括文字、图片、表格、图形等,且不会对原有文本内容造成影响。批注工具:提供多种批注工具,如注释,连线框和浮动注释,在PDF文件中添加批注和标记以便于阅读。......
  • 2024年远程控制新趋势,安全更高效,ToDesk领航远程办公
    随着科技的迅速发展和互联网的普及,远程控制技术整逐渐成为现代办公的新常态。越来越多的企业和个人开始认识到远程控制所带来的便捷性和高效性,尤其在全球化和远程办公的环境下,远程控制已成为一种不可或缺的办公工具。经过数年的沉淀和发展,远程控制软件的功能也在不断地演变和优化......
  • 2024.7.28 模拟赛10
    模拟赛\(long\long\ago\)。。。T1CompanyAcquisitions鞅的停时定理。赛时应该不可做的吧。手膜两组样例发现肯定不能用常规方法做。然后开始新科技。势能函数!!!设计一个势能函数去表示一种状态,这个势能函数要满足每操作一步势能减一,这样初势能减末势能就是期望步数。(是......
  • IntelliJ IDEA 2024.2 发布:Spring Data JPA即时查询、自动补全cron表达式
    今早看到,IntelliJIDEA2024.2发布的邮件提示,看了一眼这个版本更新的新特性真的太适合我了!也许这些能力对关注DD的小伙伴也有帮助,所以搞篇博客介绍和推荐一下。下面就来一起看看这个版本中推出的几个强大新特性。SpringDataJPA的即时查询在2024.2Ultimate版本中,对Spring......