初三奥赛模拟测试4

初三奥赛模拟测试4

崩三回

$ T1 $ 最后一课


无意义水题,全场切(除了 HANGRY_Sol 大聪明快读写挂了)
小学数学秒了

CODE

#include<bits/stdc++.h>
using namespace std;
long long k,a,b,x,y,ans;
int main()
{
    #ifndef ONLINE_JUDGE
        freopen("1.in","r",stdin);
        freopen("1.out","w",stdout);
    #endif
    scanf("%lld%lld%lld%lld%lld",&k,&a,&b,&x,&y);
    if((b>=k&&y>=k)||(b<=k&&y<=k))
        y=2*k-y,ans=(a-x)*(a-x)+(b-y)*(b-y);
    else
        ans=(a-x)*(a-x)+(b-y)*(b-y);
    printf("%lld\n",ans);
    return 0;
}

$ T2 $ 日常


依旧是水题,把区间排序之后对于每个询问二分得到它所在区间,然后直接判断即可,复杂度 \(O(klogn)\)

CODE
#include<bits/stdc++.h>
using namespace std;
long long n,m,k,d,st,ed,mid;
struct ask
{long long l,r,x,y;bool vis=0;}a[100100];
bool cmp(ask u,ask v){return u.l<v.l;}
int main()
{
    #ifndef ONLINE_JUDGE
        freopen("1.in","r",stdin);
        freopen("1.out","w",stdout);
    #endif
    scanf("%lld%lld%lld",&n,&m,&k);
    for(int i=1;i<=n;i++)
        scanf("%lld%lld%lld%lld",&a[i].l,&a[i].x,&a[i].y,&a[i].r);
    stable_sort(a+1,a+1+n,cmp);
    for(int i=1;i<=k;i++)
    {
        scanf("%lld",&d);
        st=1,ed=n;
        while(st<ed)
        {
            mid=(st+ed)>>1;
            if(d>a[mid].r)  st=mid+1;
            else            ed=mid;
        }
        if(a[st].l>d||a[ed].r<d)    
            puts("Failed");
        else if(a[st].vis==1)
            puts("Again");
        else if(a[st].x>d||a[ed].y<d)
            puts("Normal"),a[st].vis=1;
        else
            puts("Perfect"),a[st].vis=1;
    }
    return 0;
}

$ T3 $ 渡尘


子段问题显而易见的可以转化成前缀和问题,所求就是两个段头,段尾的前缀和的差的最大绝对值

设段头一段是 $ s_{a} $ ,段尾一段是 $ s_{b} $ , $ \left\vert s_{b}-s_{a} \right\vert $ 显然就等于 $ \max (s_{a}-s_{b},s_{b}-s_{a}) $ ,直接用 $ \max_{l-1 \le a \le r } s_{a} - \min_{l-1 \le a \le r } s_{a} $ \(ST\)表维护一下两项即可,时间复杂度 $ O(nlogn) $ ,赛时因为巨大常数和逆天评测机还有1s时限被卡了,另外线段树做法是 $ O(mlogn) $ 的,代码使用了 Vsinger_LouTianyi 的 $ Fastio $

CODE
#include<bits/stdc++.h>
using namespace std;
#define endl "\n"
namespace Fread{const int SIZE=(1<<18);char buf[SIZE],*S,*T;inline char getchar(){if(S==T){T=(S=buf)+fread(buf,1,SIZE,stdin);if(S==T)return '\n';}return *S++;}}
namespace Fwrite{const int SIZE=(1<<18);char buf[SIZE],*S=buf,*T=buf+SIZE;inline void flush(){fwrite(buf,1,S-buf,stdout),S=buf;}inline void putchar(char c){*S++=c;if(S==T)flush();}struct NTR{ ~NTR(){flush();}}ztr;}
#ifndef ONLINE_JUDGE
#define getchar_ getchar
#define putchar_ putchar
#else
#define getchar_ Fread::getchar
#define putchar_ Fwrite::putchar
#endif
namespace Fastio{struct Reader{template<typename T>Reader&operator>>(T&x){char c=getchar_();bool f=false;while(c<'0'||c>'9'){if(c=='-')f=true;c=getchar_();}x=0;while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar_();}if(f)x=-x;return *this;}Reader&operator>>(double & x){char c=getchar_();short f=1,s=0;x=0;double t=0;while((c<'0'||c>'9')&&c!='.'){if(c=='-')f*=-1;c=getchar_();}while(c>='0'&&c<='9'&&c!='.')x=x*10+(c^48),c=getchar_();if(c=='.')c=getchar_();else return x*=f,*this;while(c>='0'&&c<='9')t=t*10+(c^48),s++,c=getchar_();while(s--)t/=10.0;x=(x+t)*f;return*this;}Reader&operator>>(long double&x){char c=getchar_();short f=1,s=0;x=0;long double t=0;while((c<'0'||c>'9')&&c!='.'){if(c=='-')f*=-1;c=getchar_();}while(c>='0'&&c<='9'&&c!='.')x=x*10+(c^48),c=getchar_();if(c=='.')c=getchar_();else return x*=f,*this;while(c>='0'&&c<='9')t=t*10+(c^48),s++,c=getchar_();while(s--)t/=10.0;x=(x+t)*f;return*this;}Reader&operator>>(__float128&x){char c=getchar_();short f=1,s=0;x=0;__float128 t=0;while((c<'0'||c>'9')&&c!='.'){if(c=='-')f*=-1;c=getchar_();}while(c>='0'&&c<='9'&&c!='.')x=x*10+(c^48),c=getchar_();if(c=='.') c = getchar_();else return x*=f,*this;while(c>='0'&&c<='9')t=t*10+(c^48),s++,c=getchar_();while(s--)t/=10.0;x=(x+t)*f;return *this;}Reader&operator>>(char&c){c=getchar_();while(c=='\n'||c==' '||c=='\r')c=getchar_();return *this;}Reader&operator>>(char*str){int len=0;char c=getchar_();while(c=='\n'||c==' '||c=='\r')c=getchar_();while(c!='\n'&&c!=' '&&c!='\r')str[len++]=c,c=getchar_();str[len]='\0';return *this;}Reader&operator>>(string&str){char c=getchar_();str.clear();while(c=='\n'||c==' '||c=='\r')c=getchar_();while(c!='\n'&&c!=' '&&c!='\r')str.push_back(c),c=getchar_();return *this;}template<class _Tp>Reader&operator>>(vector<_Tp>&vec){for(unsigned i=0;i<vec.size();i++)cin>>vec[i];return *this;}template<class _Tp,class _tp>Reader&operator>>(pair<_Tp,_tp>&a){cin>>a.first>>a.second;return *this;}Reader(){}}cin;struct Writer{static const int set_precision = 6;typedef int mxdouble;template<typename T>Writer&operator<<(T x){if(x==0)return putchar_('0'),*this;if(x<0)putchar_('-'),x=-x;static int sta[45];int top=0;while(x)sta[++top]=x%10,x/=10;while(top)putchar_(sta[top]+'0'),--top;return*this;}Writer&operator<<(double x){if(x<0)putchar_('-'),x=-x;mxdouble _=x;x-=(double)_;static int sta[45];int top=0;while(_)sta[++top]=_%10,_/=10;if(!top)putchar_('0');while(top)putchar_(sta[top]+'0'),--top;putchar_('.');for(int i=0;i<set_precision;i++)x*=10;_=x;while(_)sta[++top]=_%10,_/=10;for(int i=0;i<set_precision-top;i++)putchar_('0');while(top)putchar_(sta[top]+'0'),--top;return*this;}Writer&operator<<(long double x){if(x<0)putchar_('-'),x=-x;mxdouble _=x;x-=(long double)_;static int sta[45];int top=0;while(_)sta[++top]=_%10,_/=10;if(!top)putchar_('0');while(top)putchar_(sta[top]+'0'),--top;putchar_('.');for(int i=0;i<set_precision;i++)x*=10;_=x;while(_)sta[++top]=_%10,_/=10;for(int i=0;i<set_precision-top;i++)putchar_('0');while(top)putchar_(sta[top]+'0'),--top;return*this;}Writer&operator<<(__float128 x){if(x<0)putchar_('-'),x=-x;mxdouble _=x;x-=(__float128)_;static int sta[45];int top=0;while(_)sta[++top]=_%10,_/=10;if(!top)putchar_('0');while(top)putchar_(sta[top]+'0'),--top;putchar_('.');for(int i=0;i<set_precision;i++)x*=10;_=x;while(_)sta[++top]=_%10,_/=10;for(int i=0;i<set_precision-top;i++)putchar_('0');while(top)putchar_(sta[top]+'0'),--top;return*this;}Writer&operator<<(char c){putchar_(c);return*this;}Writer&operator<<(char*str){int cur=0;while(str[cur])putchar_(str[cur++]);return *this;}Writer&operator<<(const char*str){int cur=0;while(str[cur])putchar_(str[cur++]);return *this;}Writer&operator<<(string str){int fir=0,ed=str.size();while(fir<ed) putchar_(str[fir++]);return *this;}template<class _Tp>Writer&operator<<(vector<_Tp>vec){for(unsigned i=0;i<vec.size()-1;i++)cout<<vec[i]<<" ";cout<<vec[vec.size()-1];return *this;}template<class _Tp,class _tp>Writer&operator<<(pair<_Tp,_tp>a){cout<<a.first<<" "<<a.second;return *this;}Writer(){}}cout;}
#define cin  Fastio::cin
#define cout  Fastio::cout
long long n,m,a[201000],s[201000],ST[201000][40][2],lb[201000],x,y;
inline long long check_max(int st,int ed)
{
    long long dis=lb[ed-st+1];
    return max(ST[st][dis][0],ST[ed-(1<<dis)+1][dis][0]);
}
inline long long check_min(int st,int ed)
{
    long long dis=lb[ed-st+1];
    return min(ST[st][dis][1],ST[ed-(1<<dis)+1][dis][1]);
}
int main()
{
    cin>>n>>m;
    for(register int i=1;i<=n;i++)
        cin>>a[i];
    for(register int i=1;i<=n;i++)
        s[i]=s[i-1]+a[i],ST[i][0][0]=ST[i][0][1]=s[i];
    for(int i=1,mid=0;i<=n+2;i++)
    {
        if(i==(1<<(mid+1)))   mid++;
        lb[i]=mid;
    }
    for(register int i=n;i>=0;i--)
        for(register int j=1;j<=lb[n-i+1];j++)
            ST[i][j][0]=max(ST[i][j-1][0],ST[i+(1<<(j-1))][j-1][0]),
            ST[i][j][1]=min(ST[i][j-1][1],ST[i+(1<<(j-1))][j-1][1]);
    for(register int i=1;i<=m;i++)
    {
        cin>>x>>y;
        cout<<check_max(x-1,y)-check_min(x-1,y)<<endl;
    }
    return 0;
}

$ T4 $ 罪人挽歌


蚌,赛时欧拉路写挂了,爆零了

首先,根据题意,相当于如果前两个二元组是 \(first\) 一样的话,第三个和第二个一定是 \(second\) 一样,类似这样交替

我们发现可以根据每个二元组建图,如果这次走正边(就是说从左边相同到右边相同),下次就要走反边,之后遍历每条边

容易发现这玩意其实是个强大欧拉路,对于每个点在正图(有向)里如果入度是奇数,那么它一定是 起点/终点(因为这样的话它总有一条边走不了),入度同理,所以处理出 入度为奇数的点个数加上出度为奇数的点的个数,设为 \(k\) ,如果为 \(2\) ,这两个点分别是起点和终点(两个点重合也行),如果是 \(0\) 则从任意一点出发总有一条合法的欧拉回路,上述结论可以归纳证明

直接 \(dfs\) 一遍贪心即可,需要保证走完每一步之后图依然联通,回溯的时候把后面整个插入到这条边后面,我直接链表维护了,注意删边,否则就会导致无用边重复遍历退化成 $ O(n^2) $ 对于 \(k=2\) 枚举两个起点,然后比较字典序即可,对于 \(k=0\) 可以删去任何一条边,所以第一步一定走编号是一的边(除非它是桥),复杂度 $ O(n) $ 的

CODE
#include<bits/stdc++.h>
using namespace std;
#define N 501000
long long n,a[N],b[N],head1[N],head2[N],in[N],out[N],c,num1[N],num2[N],us1[N],us2[N],siz;
bool vis[N],jud;
vector<int> vec1,vec2;
struct NODE{long long nxt,ele;}ans1[N],ans[N];
struct EDGE{long long to,nxt;}e1[N],e2[N];
void insert(NODE& now,int d){ans[++siz].nxt=now.nxt,now.nxt=siz,ans[siz].ele=d;}
void add(int fr,int ed,int r)
{
    e1[r].nxt=head1[fr];
    head1[fr]=r;
    e1[r].to=ed;
    e2[r].nxt=head2[ed];
    head2[ed]=r;
    e2[r].to=fr;
}
void clear()
{
    memcpy(us1,head1,sizeof(head1));
    memcpy(us2,head2,sizeof(head2));
    memset(vis,0,sizeof(vis));
	siz=0;
    memset(ans,0,sizeof(ans));
}
void dfs(int now,int state,NODE& p)
{
    long long mid=0;
    if(state==1)
    {
		while(1)
		{
        	mid=us1[now];
        	while(vis[mid]==1)
            	mid=e1[mid].nxt;
        	us1[now]=mid;
        	if(mid==0)
            	return;
       		vis[mid]=1;
        	insert(p,mid);
        	dfs(e1[mid].to,state^1,ans[p.nxt]);
		}
    }
    if(state==0)
    {
		while(1)
		{
        	mid=us2[now];
        	while(vis[mid]==1)
            	mid=e2[mid].nxt;
        	us2[now]=mid;
        	if(mid==0)
            	return;
        	vis[mid]=1;
        	insert(p,mid);
        	dfs(e2[mid].to,state^1,ans[p.nxt]);
		}
    }
}
void rr(){memcpy(ans1,ans,sizeof(ans1));}
void change(NODE* Q)
{
	vec1.clear();
    for(int i=Q[0].nxt;i>0;i=Q[i].nxt)
        vec1.push_back(Q[i].ele);
}
int main()
{
    #ifndef ONLINE_JUDGE
        freopen("1.in","r",stdin);
        freopen("1.out","w",stdout);
    #endif
    scanf("%lld",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%lld%lld",&a[i],&b[i]);
        if(out[a[i]]==0)
            num1[a[i]]=i;
        if(in[b[i]]==0)
            num2[b[i]]=i;
        out[a[i]]++,in[b[i]]++;
    }
    for(int i=n;i>=1;i--)
        add(a[i],b[i],i);
    for(int i=1;i<=n;i++)
    {
        if(in[i]&1==1)    c++;
        if(out[i]&1==1)   c++;
    }
    if(c!=0&&c!=2){puts("No");return 0;}
    puts("Yes");
    if(c==0)
    {
        clear();
        dfs(b[1],0,ans[0]),rr();
        clear();
        dfs(a[1],1,ans[0]);
    }
    else
    {
        for(int i=1;i<=n;i++)
        {
            if(in[i]&1==1)     
            {
                clear(),dfs(i,0,ans[0]);
                if(jud==0)
                    rr(),jud=1;
                else
                    break;
            }
            if(out[i]&1==1)    
            {   
                clear(),dfs(i,1,ans[0]);
                if(jud==0)
                    rr(),jud=1;
                else
                    break;
            }
        }
    }
	change(ans),vec2=vec1;change(ans1);
	if(vec2<vec1)	
		for(int i=0;i<n;i++)
			printf("%d ",vec2[i]);
	else			
		for(int i=0;i<n;i++)
			printf("%d ",vec1[i]);
	puts("");
    return 0;
}
posted @ 2024-04-06 15:37  wang54321  阅读(31)  评论(2编辑  收藏  举报