2.28杂题选讲

T1

曾老师做法:把限制从小到大排序,然后¥%……—*(—……%

曾老师太神仙了吊打官方题解QwQ

然而我觉得官方题解更好懂QwQ

#include<bits/stdc++.h>
//clock_t t=clock();
namespace my_std{
    using namespace std;
    #define pii pair<int,int>
    #define fir first
    #define sec second
    #define MP make_pair
    #define rep(i,x,y) for (int i=(x);i<=(y);i++)
    #define drep(i,x,y) for (int i=(x);i>=(y);i--)
    #define go(x) for (int i=head[x];i;i=edge[i].nxt)
    #define templ template<typename T>
    #define sz 1010
    #define mod 1000000007ll
    typedef long long ll;
    typedef double db;
    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
    templ inline T rnd(T l,T r) {return uniform_int_distribution<T>(l,r)(rng);}
    templ inline bool chkmax(T &x,T y){return x<y?x=y,1:0;}
    templ inline bool chkmin(T &x,T y){return x>y?x=y,1:0;}
    templ inline void read(T& t)
    {
        t=0;char f=0,ch=getchar();double d=0.1;
        while(ch>'9'||ch<'0') f|=(ch=='-'),ch=getchar();
        while(ch<='9'&&ch>='0') t=t*10+ch-48,ch=getchar();
        if(ch=='.'){ch=getchar();while(ch<='9'&&ch>='0') t+=d*(ch^48),d*=0.1,ch=getchar();}
        t=(f?-t:t);
    }
    template<typename T,typename... Args>inline void read(T& t,Args&... args){read(t); read(args...);}
    char sr[1<<21],z[20];int C=-1,Z=0;
    inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
    inline void print(register int x)
    {
    	if(C>1<<20)Ot();if(x<0)sr[++C]='-',x=-x;
    	while(z[++Z]=x%10+48,x/=10);
    	while(sr[++C]=z[Z],--Z);sr[++C]='\n';
    }
//    void file()
//    {
//        #ifndef ONLINE_JUDGE
//        freopen("a.in","r",stdin);
//        #endif
//    }
//    inline void chktime()
//    {
//        #ifndef ONLINE_JUDGE
//        cout<<(clock()-t)/1000.0<<'\n';
//        #endif
//    }
//    #ifdef mod
//    ll ksm(ll x,int y){ll ret=1;for (;y;y>>=1,x=x*x%mod) if (y&1) ret=ret*x%mod;return ret;}
//    ll inv(ll x){return ksm(x,mod-2);}
//    #else
//    ll ksm(ll x,int y){ll ret=1;for (;y;y>>=1,x=x*x) if (y&1) ret=ret*x;return ret;}
//    #endif
//	inline ll mul(ll a,ll b){ll d=(ll)(a*(double)b/mod+0.5);ll ret=a*b-d*mod;if (ret<0) ret+=mod;return ret;}
}
using namespace my_std;

int n,m;
bool visa[sz*sz],visb[sz*sz];

int main()
{
//	file();
	read(n,m);
	int x;
	rep(i,1,n)
	{
		read(x);
		if (visa[x]) return puts("0"),0;
		else visa[x]=1;
	}
	rep(i,1,m)
	{
		read(x);
		if (visb[x]) return puts("0"),0;
		else visb[x]=1;
	}
	ll ans=1;
	ll A=0,B=0;
	drep(i,n*m,1)
	{
		ll AA=A,BB=B;
		if (visa[i]) AA=1,++A;
		if (visb[i]) BB=1,++B;
		if (visa[i]||visb[i]) ans=ans*AA%mod*BB%mod;
		else ans=ans*(1ll*AA*BB-(1ll*n*m-i))%mod;
	}
	cout<<ans;
	return 0;
}

T2

曾老师做法:发现1~n这一条链上点的编号是单调递增的,然后¥%……—(*—……

曾老师太神仙了吊打我QwQ

然而我觉得暴力分治之后最小生成树更好想QwQ

#include<bits/stdc++.h>
//clock_t t=clock();
namespace my_std{
    using namespace std;
    #define pii pair<int,int>
    #define fir first
    #define sec second
    #define MP make_pair
    #define rep(i,x,y) for (int i=(x);i<=(y);i++)
    #define drep(i,x,y) for (int i=(x);i>=(y);i--)
    #define go(x) for (int i=head[x];i;i=edge[i].nxt)
    #define templ template<typename T>
    #define sz 202002
    typedef long long ll;
    typedef double db;
    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
    templ inline T rnd(T l,T r) {return uniform_int_distribution<T>(l,r)(rng);}
    templ inline bool chkmax(T &x,T y){return x<y?x=y,1:0;}
    templ inline bool chkmin(T &x,T y){return x>y?x=y,1:0;}
    templ inline void read(T& t)
    {
        t=0;char f=0,ch=getchar();double d=0.1;
        while(ch>'9'||ch<'0') f|=(ch=='-'),ch=getchar();
        while(ch<='9'&&ch>='0') t=t*10+ch-48,ch=getchar();
        if(ch=='.'){ch=getchar();while(ch<='9'&&ch>='0') t+=d*(ch^48),d*=0.1,ch=getchar();}
        t=(f?-t:t);
    }
    template<typename T,typename... Args>inline void read(T& t,Args&... args){read(t); read(args...);}
    char sr[1<<21],z[20];int C=-1,Z=0;
    inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
    inline void print(register int x)
    {
        if(C>1<<20)Ot();if(x<0)sr[++C]='-',x=-x;
        while(z[++Z]=x%10+48,x/=10);
        while(sr[++C]=z[Z],--Z);sr[++C]='\n';
    }
//    void file()
//    {
//        #ifndef ONLINE_JUDGE
//        freopen("a.in","r",stdin);
//        #endif
//    }
//    inline void chktime()
//    {
//        #ifndef ONLINE_JUDGE
//        cout<<(clock()-t)/1000.0<<'\n';
//        #endif
//    }
//    #ifdef mod
//    ll ksm(ll x,int y){ll ret=1;for (;y;y>>=1,x=x*x%mod) if (y&1) ret=ret*x%mod;return ret;}
//    ll inv(ll x){return ksm(x,mod-2);}
//    #else
//    ll ksm(ll x,int y){ll ret=1;for (;y;y>>=1,x=x*x) if (y&1) ret=ret*x;return ret;}
//    #endif
//  inline ll mul(ll a,ll b){ll d=(ll)(a*(double)b/mod+0.5);ll ret=a*b-d*mod;if (ret<0) ret+=mod;return ret;}
}
using namespace my_std;

int n;
ll D;
ll a[sz];

struct hh{int u,v;ll w;inline const bool operator < (const hh &y) const {return w<y.w;}}edge[sz*30];
int ecnt;
int fa[sz];
int getfa(int x){return fa[x]==x?x:fa[x]=getfa(fa[x]);}

void link(int x,int y){edge[++ecnt]=(hh){x,y,D*(y-x)+a[x]+a[y]};}
int solve(int l,int r,int opt)
{
	if (l==r) return l;
	int mid=(l+r)>>1;
	int L=solve(l,mid,-1),R=solve(mid+1,r,1);
	rep(i,l,mid) link(i,R);
	rep(i,mid+1,r) link(L,i);
	ll mn=1e18;int ret;
	rep(i,l,r) if (chkmin(mn,D*opt*i+a[i])) ret=i;
	return ret;
}
ll solve()
{
	rep(i,1,n) fa[i]=i;
	sort(edge+1,edge+ecnt+1);
	ll ret=0;
	rep(i,1,ecnt)
	{
		int u=getfa(edge[i].u),v=getfa(edge[i].v);
		if (u!=v) ret+=edge[i].w,fa[u]=v;
	}
	return ret;
}

int main()
{
//    file();
	read(n,D);
	rep(i,1,n) read(a[i]);
	solve(1,n,0);
	cout<<solve();
	return 0;
}

T3

似乎很神仙,但成功听懂了。

果然hz大佬的题更亲民QwQ

#include<bits/stdc++.h>
//clock_t t=clock();
namespace my_std{
    using namespace std;
    #define pii pair<int,int>
    #define fir first
    #define sec second
    #define MP make_pair
    #define rep(i,x,y) for (int i=(x);i<=(y);i++)
    #define drep(i,x,y) for (int i=(x);i>=(y);i--)
    #define go(x) for (int i=head[x];i;i=edge[i].nxt)
    #define templ template<typename T>
    #define sz 102020
    typedef long long ll;
    typedef double db;
    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
    templ inline T rnd(T l,T r) {return uniform_int_distribution<T>(l,r)(rng);}
    templ inline bool chkmax(T &x,T y){return x<y?x=y,1:0;}
    templ inline bool chkmin(T &x,T y){return x>y?x=y,1:0;}
    templ inline void read(T& t)
    {
        t=0;char f=0,ch=getchar();double d=0.1;
        while(ch>'9'||ch<'0') f|=(ch=='-'),ch=getchar();
        while(ch<='9'&&ch>='0') t=t*10+ch-48,ch=getchar();
        if(ch=='.'){ch=getchar();while(ch<='9'&&ch>='0') t+=d*(ch^48),d*=0.1,ch=getchar();}
        t=(f?-t:t);
    }
    template<typename T,typename... Args>inline void read(T& t,Args&... args){read(t); read(args...);}
    char sr[1<<21],z[20];int C=-1,Z=0;
    inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
    inline void print(register int x)
    {
        if(C>1<<20)Ot();if(x<0)sr[++C]='-',x=-x;
        while(z[++Z]=x%10+48,x/=10);
        while(sr[++C]=z[Z],--Z);sr[++C]='\n';
    }
//    void file()
//    {
//        #ifndef ONLINE_JUDGE
//        freopen("a.in","r",stdin);
//        #endif
//    }
//    inline void chktime()
//    {
//        #ifndef ONLINE_JUDGE
//        cout<<(clock()-t)/1000.0<<'\n';
//        #endif
//    }
//    #ifdef mod
//    ll ksm(ll x,int y){ll ret=1;for (;y;y>>=1,x=x*x%mod) if (y&1) ret=ret*x%mod;return ret;}
//    ll inv(ll x){return ksm(x,mod-2);}
//    #else
//    ll ksm(ll x,int y){ll ret=1;for (;y;y>>=1,x=x*x) if (y&1) ret=ret*x;return ret;}
//    #endif
//  inline ll mul(ll a,ll b){ll d=(ll)(a*(double)b/mod+0.5);ll ret=a*b-d*mod;if (ret<0) ret+=mod;return ret;}
}
using namespace my_std;

int n,m;
struct hh{int u,v,w;}edge[sz];
inline bool cmp(const hh &x,const hh &y){return x.w<y.w;}

int fa[sz];
ll sum[sz];
int cnt[sz];
int getfa(int x){return x==fa[x]?x:fa[x]=getfa(fa[x]);}

int main()
{
//    file();
	read(n,m);
	rep(i,1,n) read(sum[fa[i]=i]);
	int x,y,z;
	rep(i,1,m) read(x,y,z),edge[i]=(hh){x,y,z};
	sort(edge+1,edge+m+1,cmp);
	int ans=0;
	rep(i,1,m)
	{
		int u=edge[i].u,v=edge[i].v;
		u=getfa(u),v=getfa(v);
		if (u!=v) fa[u]=v,sum[v]+=sum[u],cnt[v]+=cnt[u],cnt[u]=sum[u]=0;
		++cnt[v];
		if (sum[v]>=edge[i].w) ans+=cnt[v],cnt[v]=0;
	}
	cout<<m-ans;
	return 0;
}

T4

这题就是我选的啦。

你们的题都这么难,我当然要给一道SB题啦。

但是…这么简单的题你们竟然不做…你们欺人太甚……

一定是看这题太简单不想做了……

我的题解

posted @ 2019-03-02 22:23  p_b_p_b  阅读(221)  评论(0编辑  收藏  举报