2022.9.27———HZOI【CSP-S模拟13】游寄

Preface

排名 Rank32/43

得分 0pts + 0pts + 15pts + 0pts = 15pts

T1:排序,T2:Xorum,T3:有趣的区间问题,T4:无聊的卡牌问题

T1 

CF1375E 的弱化版

注意是弱化版不是原题。

考试的时候就没注意这个题目名,像 NOI Online2022 某丹钓战一样。

正解就是个排序。。。

先简要说一下题意,给你一个排列 a,要求你找出 a 中所有的逆序对之后,将逆序对们以某一种方式排列,使得按照这个排列进行 swap 操作之后的 a 序列是单调 递增的。

注意所有的逆序对都需要用上

然后就是排序了,第一关键字按照左端点升序排,第二关键字按照右端点的值降序排即可。

证明不会。kiriotkazuto 的博客

T1
#include <iostream>
#include <algorithm>
#define GMY (520&1314)
#define FBI_OPENTHEDOOR(x, y) freopen(#x ".in", "r", stdin), freopen(#y ".out", "w", stdout);
#define re register int
#define char_phi signed
#define DMARK cerr << "###"
#define _ ' '
#define Endl cout << '\n'
#define Dl cerr << '\n'
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define N 1005
using namespace std;
inline void Fastio_setup(){ios::sync_with_stdio(false); cin.tie(NULL), cout.tie(NULL);}
int n, nxdcnt;
int s[N];
struct Nxd{
	int l, r;
	friend bool operator < (Nxd A, Nxd B){return ((A.l == B.l) ? (s[A.r] > s[B.r]) : (A.l < B.l));}
};
/*
	所以先按照左端点升序排
	第二关键字再按照右端点的a[j]降序排
*/
struct Nxd a[N*N];

inline void work(){
	cin >> n;
	for (re i = 1 ; i <= n ; ++ i)
		cin >> s[i];
	
	for (re i = 1 ; i <= n ; ++ i){
		for (re j = i+1 ; j <= n ; ++ j){
			if (s[i] > s[j])
				a[++ nxdcnt] = (Nxd){i, j};
		}
	}
	sort(a+1, a+nxdcnt+1);
	
	cout << nxdcnt << '\n';
	for (re i = 1 ; i <= nxdcnt ; ++ i)
		cout << a[i].l << _ << a[i].r << '\n';
}
// #define IXINGMY
char_phi main(){
	#ifdef IXINGMY
		FBI_OPENTHEDOOR(a, a);
	#endif
	Fastio_setup();
	work();
	return GMY;
}

T2 Xorum

CF1427E

这个题我写题解了,可以去康,这里不再粘过来了

T2
#include <iostream>
#include <bitset>
#define GMY (520&1314)
#define FBI_OPENTHEDOOR(x, y) freopen(#x ".in", "r", stdin), freopen(#y ".out", "w", stdout);
#define re register int
#define char_phi signed
#define N 100005
using namespace std;
inline void Fastio_setup(){ios::sync_with_stdio(false); cin.tie(NULL), cout.tie(NULL);}

struct Answer{int opt; long long x, y;};

long long x, y, z, a, tmp, plc, anscnt, b, c, d;
struct Answer ans[N];

#define lowbit(x) ((x) & (-(x)))
inline void Xiao(){
    tmp = x; y = x;
    while (tmp != 0)// 取出来x的最高位
        plc = lowbit(tmp), tmp ^= plc;
    while (lowbit(y) != plc)
        {ans[++ anscnt] = (Answer){1, y, y}; y <<= 1;}// 得到y
    // 对齐之后另其与x异或
    ans[++ anscnt] = (Answer){2, x, y};
    z = x ^ y;
    // 另z与y相加得到a
    ans[++ anscnt] = (Answer){1, y, z};
    a = y + z;
    // y左移
    ans[++ anscnt] = (Answer){1, y, y};
    d = y + y;
    // a与y与x异或
    ans[++ anscnt] = (Answer){2, a, d};
    ans[++ anscnt] = (Answer){2, a^d, x};
    b = a ^ d ^ x;
    // 用b去消y
    c = b>>1;
    while (y != c){
        if ((y & b) == b)
            {ans[++ anscnt] = (Answer){2, y, b}, y = y ^ b;}
        ans[++ anscnt] = (Answer){1, b, b}; b <<= 1;
    }
    // 此时剩下的y就是x最高位了
    ans[++ anscnt] = (Answer){2, y, x};
    x = x ^ y;
}

inline void work(){
    cin >> x;

    while (x != 1)
        Xiao();

    cout << anscnt << '\n';
    for (re i = 1 ; i <= anscnt ; ++ i){
        cout << ans[i].x;
        cout << ((ans[i].opt == 1) ? (" + ") : (" ^ "));
        cout << ans[i].y << '\n';
    }
}
// #define IXINGMY
char_phi main(){
    #ifdef IXINGMY
        FBI_OPENTHEDOOR(a, a);
    #endif
    Fastio_setup();
    work();
    return GMY;
}

然后我在这里挂一下各位其他人的随机化代码,造福后人(专门给学弟学妹们看的(


eafoo 的,好家伙直接 A

用的是 exgcd,我根本看不懂(

eafoo·100pts
#include <bits/stdc++.h>
#define ff fflush(stdout)
#define thank puts("感恩😅😅😅😅"), ff
#define bug(...) fprintf(stderr, __VA_ARGS__)
#define fop(x, l, r) for (register int x = l; x <= r; ++x)
#define fio(x, r, l) for (register int x = r; x >= l; --x)
#define edg(x, u) for (int x = head[u]; x; x = nxt[x])
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define int ll
const int mod = 1e9 + 7, inf = 0x3f3f3f3f3f3f3f3fll;
void ckmax(int &a, int b) { a = max(a, b); }
void ckmin(int &a, int b) { a = min(a, b); }
void amod(int &a, int b) { a += b; if (a >= mod) a -= mod; }
void mmod(int &a, int b) { a = 1ll * a * b % mod; }
void smod(int &a, int b) { a -= b; if (a < 0) a += mod; } 
int amo(int a, int b) { int c = a + b; if (c >= mod) c -= mod; return c; }
int mmo(int a, int b) { return 1ll * a * b % mod; }
int smo(int a, int b) { int c = a - b; if (c < 0) c += mod; return c; }
int read() {
    int x = 0; char c; bool f = 0; 
    while (!isdigit(c = getchar())) if (c == '-') f = 1; 
    do x = (x << 1) + (x << 3) + (c ^ 48); while (isdigit(c = getchar())); 
    return f ? -x : x;
}


mt19937 rnd(chrono::system_clock::now().time_since_epoch().count());
int rand(int l, int r) { return (uniform_int_distribution<int>(l, r))(rnd); }

const int maxn = 5e6 + 10;

int num[maxn], tot;
int op[maxn][3], cnt;

void Work() {
    int x = rand(1, tot), y = rand(1, tot);
    int opt = rand(1, 2);
    if (x == y || opt == 1) {
        if (num[x] + num[y] > 100000000000000000ll) return; 
        num[++tot] = num[x] + num[y];
        op[++cnt][0] = 1, op[cnt][1] = num[x], op[cnt][2] = num[y];
    }
    else {
        if ((num[x] ^ num[y]) > 100000000000000000ll) return;
        num[++tot] = num[x] ^ num[y];
        op[++cnt][0] = 2, op[cnt][1] = num[x], op[cnt][2] = num[y];
    }
}

int exgcd(int a, int b, ll &x, ll &y) {
    if (b == 0) return x = 1, y = 0, a;
    int res = exgcd(b, a % b, y, x);
    return y -= a / b * x, res;
}

void Work(int a, int b) {
    int ans = 0;
    while (b) {
        if (b & 1) op[++cnt][0] = 1, op[cnt][1] = ans, op[cnt][2] = a, ans += a;
        op[++cnt][0] = 1, op[cnt][1] = a, op[cnt][2] = a, a += a, b >>= 1;
    }
}

signed main() {
    int x = read();
    num[++tot] = x;
    op[++cnt][0] = 2, op[cnt][1] = x, op[cnt][2] = x;
    fop(i, 1, 10000) Work();
    fop(i, 1, tot) fop(j, 1, tot) if (__gcd(num[i], num[j]) == 1) {
        int x, y;
        exgcd(num[i], num[j], x, y);
        if (x < 0) swap(x, y), swap(num[i], num[j]);
        if (((num[i] * x) ^ (num[j] * -y)) != 1) continue;
        Work(num[i], x), Work(num[j], -y);
        op[++cnt][0] = 2, op[cnt][1] = num[i] * x, op[cnt][2] = num[j] * -y;
        printf("%lld\n", cnt);
        fop(i, 1, cnt) printf("%lld %lld %lld\n", op[i][0], op[i][1], op[i][2]);
        return 0;
    }
}

然后是 SMTwy 的,用的似乎是朴素的随机化,但是通过一些方法拿到了 91pts 的高分

SMTwy·91pts
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <unordered_map>
using namespace std;
typedef long long ll;
const int mx=3e6+1000;
const int lim=3e6;
const int B=233;
const int mod=1e9+7;
ll x,lin[mx],li=0;;
int an;
struct N{
    ll a,b,c;
}opt;
set <ll> S;
unordered_map <ll,ll> mp;
unordered_map <ll,N> pre;
unordered_map <ll,ll> vis;
ll x1,x2,x3,x4;
struct A{
    int ty;
    ll a,b,c;
}ans[mx],an1[mx];
inline bool check(ll xx){
    if(mp[xx-1]){
        if(((xx-1)^xx)==1){
            x1=xx;x2=xx-1;
            ans[++an].a=x1,ans[an].b=x2;ans[an].c=1;
            ans[an].ty=2;
            return 1;
        }
        else {
            x1=xx;x2=xx-1;
            x3=x1+x;
            ans[++an].a=x1,ans[an].b=x;ans[an].c=x3;
            ans[an].ty=1;
            x4=x2+x;
            ans[++an].a=x2,ans[an].b=x;ans[an].c=x4;
            ans[an].ty=1;
            ans[++an].a=x3,ans[an].b=x4;ans[an].c=1;
            ans[an].ty=2;
            return 1;
        }
    }
    if(mp[xx+1]){
        if(((xx+1)^xx)==1){
            x1=xx;x2=xx+1;
            ans[++an].a=x1;ans[an].b=x2;ans[an].c=1;
            ans[an].ty=2;
            return 1;
        }
        else {
            x1=xx;x2=xx+1;
            x3=x1+x;
            ans[++an].a=x1,ans[an].b=x;ans[an].c=x3;
            ans[an].ty=1;
            x4=x2+x;
            ans[++an].a=x2,ans[an].b=x;ans[an].c=x4;
            ans[an].ty=1;
            ans[++an].a=x3,ans[an].b=x4;ans[an].c=1;
            ans[an].ty=2;
            return 1;

        }
    }
    return 0;
}
void dfs(ll u){
    if(u==0)return ;
    if(u==x)return ;
    N optt=pre[u];
    if(vis[optt.a]==0){
        vis[optt.a]=1;
        dfs(optt.a);
    }
    if(vis[optt.b]==0){
        vis[optt.b]=1;
        dfs(optt.b);
    }
}
int moo=0;
void MYH(){
    scanf("%lld",&x);
    mp[x]=1;vis[x]=1;
    moo=x%(rand()%48967)%27+1;
    if(moo==1)moo=7;
    S.insert(x);int tot=1;
    ll last=0;mp[0]=1;
    int uoo=0;
    while(1){
        if(tot==lim)return ; li=0;
        auto pos=S.begin();
        ll op=(last*B%mod*tot*x-rand()%moo)%(S.size());
        if(op==0)pos=(--S.end());
        else {while(op){op--;pos++;}}      
        last=*pos;if(S.size()>140)uoo=op%7+1;
        int uop=0;
        for(auto it : S){
           // if(it>1e9)break;
            if(uop<uoo){
                uop++;continue;
            }
            else uop=0;
            ll o1=it+(*pos);
            ll o2=it^(*pos);
            if(mp[o1]==0){
                mp[o1]=1;
                if(o1>1e12)continue;
                tot++;ans[++an].ty=1;ans[an].a=it;ans[an].b=*pos;ans[an].c=o1;
                if(tot==lim)return ;lin[++li]=o1;
                opt.a=it,opt.b=*pos;pre[o1]=opt;
                if(check(o1))return ;
            }
            if(mp[o2]==0){
                mp[o2]=1;
                if(o2>1e12)continue;
                tot++;ans[++an].ty=2;ans[an].a=it,ans[an].b=*pos;ans[an].c=o2;
                if(tot==lim)return ;lin[++li]=o2;
                opt.a=it,opt.b=*pos;pre[o2]=opt;
                if(check(o2))return ;
            }
        }
        for(int i=1;i<=li;++i){
        //    if(lin[i]>1e12)continue;
            S.insert(lin[i]);
        }
    }
}
int main(){
    srand((unsigned)(time(0)));
    MYH();
    if(x1==0 && x2==0){
        printf("ooooooooopppppppppp\n");
        return 0;
    }
    if(an>1e5){
        dfs(x1);dfs(x3);
        dfs(x2);dfs(x4);
        vis[1]=1;
       // printf("x1=%lld x2=%lld x3=%lld x4=%lld\n",x1,x2,x3,x4);
        vis[x1]=1;vis[x2]=1;vis[x3]=1;vis[x4]=1;
        int ann=0;
     //   printf("%lld %lld %lld %lld\n",ans[an].a,ans[an].b,ans[an-1].a,ans[an-1].b);
        for(int i=1;i<=an;++i){
            if(vis[ans[i].c]==1){
                ann++;an1[ann]=ans[i];
            }
        }
      //  an1[++ann].ty=2;
      //  an1[ann].a=x1;
      //  an1[ann].b=x2;
        printf("%d\n",ann);
        for(int i=1;i<=ann;++i){
            printf("%d %lld %lld\n",an1[i].ty,an1[i].a,an1[i].b);
        }
        return 0;
    }
    printf("%d\n",an);
    for(int i=1;i<=an;++i){
        printf("%d %lld %lld\n",ans[i].ty,ans[i].a,ans[i].b);
    }
    return 0;
}

然后是 Delov 的,这个就是我题解说的那个构造操作数列随机化的大佬

Delov·94pts


#include <bits/stdc++.h>
typedef long long ll;typedef unsigned long long ull; typedef double db;typedef long double ldb;
#define fre(x) freopen(#x ".in","r",stdin),freopen(#x ".out","w",stdout)
#define Rep(i,a,b) for(int i=a;i<=b;++i) 
#define Dwn(i,a,b) for(int i=a;i>=b;--i)
#define pii pair<int,int>
#define mair make_pair
#define fir first
#define sec second
#define int ll
using namespace std;

const int maxn=1e5+10,B=9;

mt19937 mt((ull)&maxn);
int Mtrand(int l,int r){return uniform_int_distribution<>(l,r)(mt);}
int ST;
set<int>S;
struct Ver{ int p,a,b; void Print(){cout<<p<<" "<<a<<" "<<b<<"\n";} };
vector<Ver>Ans; vector<int>vec;

int opt[B][20]={
	{1,1,1,1,1,1,1,1,1,1,1,1,1,2,2},
	{1,2,1,1,2,1,2,1,1,2},
	{1,1,1,1,2,1,1,2,1,2},
	{1,1,1,1,1,1,1,2,1,2},
	{1,1,1,1,1,1,2,1,1,1,2},
	{1,1,1,1,1,1,1,1,2,1,1,1,2},
	{1,1,1,1,1,1,1,1,1,1,1,1,2,1,2},
	{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2},
	{1,1,1,2,1,1,2,1,1,1,1,2,1,1,1,1,2,2},
};

int ops[B]={15,10,10,10,11,13,15,17,18};

pii Rp(){ return mair(vec[Mtrand(0,vec.size()-1)],vec[Mtrand(0,vec.size()-1)]); }

void Out1(int x){
	cout<<Ans.size()+1<<"\n";
	for(auto it : Ans)it.Print();
	if(x&1){ cout<<"2 "<<x-1<<" "<<x<<"\n"; }
	else {cout<<"2 "<<x+1<<" "<<x<<"\n";}
}

void Out2(int x){
	cout<<Ans.size()+3<<"\n";
	for(auto it : Ans)it.Print();
	if(x&1){
		cout<<1<<" "<<ST<<" "<<x<<"\n";
		cout<<1<<" "<<ST<<" "<<x+1<<"\n";
		cout<<2<<" "<<ST+x<<" "<<ST+x+1<<"\n";
	}else{
		cout<<1<<" "<<ST<<" "<<x<<"\n";
		cout<<1<<" "<<ST<<" "<<x-1<<"\n";
		cout<<2<<" "<<ST+x<<" "<<ST+x-1<<"\n";
	}
}

void Out(){ cout<<Ans.size()<<"\n";for(auto it : Ans)it.Print(); }

void solve(){
	cin>>ST;
	int cs=0;
	do{	
		S.clear(),Ans.clear(),vec.clear();
		S.insert(ST);vec.push_back(ST);
		int i;
		cs%=B;
		for(i=0;vec.size()<100000 && ((*S.begin())>1);++i){
			int t=opt[cs][i%ops[cs]];pii it=Rp();
			int New=0;
			if(t==1)New=it.fir+it.sec;
			else New=it.fir^it.sec;
			if(!New || (S.find(New)!=S.end())){continue;}
			Ans.push_back(Ver{t,it.fir,it.sec});S.insert(New);vec.push_back(New);
			if(New==1)return Out();
			if(New&1){
				if(S.find(New-1)!=S.end())return Out1(New);
				if(S.find(New+1)!=S.end())return Out2(New);
			}else{
				if(S.find(New+1)!=S.end())return Out1(New);
				if(S.find(New-1)!=S.end())return Out2(New);
			}
		}
		++cs;
		cerr<<cs<<"\n";
	}while(1.0*clock()/CLOCKS_PER_SEC<=0.900);
}

#undef int
int main (){ ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);return solve(),0; }

T3 

CF1609F

没改(

T4 

CF1427F

神奇黑题,建议看洛谷题解

实际上 kiritokazuto 说的那个建反图没必要,我就没建,跟他跑的一样,照样 A

T4
#include <iostream>
#define GMY (520&1314)
#define FBI_OPENTHEDOOR(x, y) freopen(#x ".in", "r", stdin), freopen(#y ".out", "w", stdout);
#define re register int
#define char_phi signed
#define DMARK cerr << "###"
#define _ ' '
#define Endl cout << '\n'
#define Dl cerr << '\n'
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define N 205
using namespace std;
inline void Fastio_setup(){ios::sync_with_stdio(false); cin.tie(NULL), cout.tie(NULL);}
/*
	WA
	非逼我模大样例是吧
	大样例没错,淦
	模测试点!md
	处理没问题,问题在输出
*/
/*
	5
	1 2 3 4 5 9 11 12 13 18 19 20 21 22 23
*/

int n, top, ider;
char tp[N*6], vis[N*2];
int du[N*6], pos[N*6], s[N*6];
int ans[N*6][5];

struct Kuai{int belong, num, tag;} a[N*2];

inline void work(){
	cin >> n;
	for (re i = 1, w ; i <= n*3 ; ++ i)
		{cin >> w; tp[w] = 1;}
	
	
	n *= 6;
	/*for (re i = 1 ; i <= n ; ++ i)
		cerr << (int)tp[i] << _;
	Dl;*/
	for (re i = 1 ; i <= n ; ++ i){
		// cerr << "id " << i << _ << ider << _ << top << _ << s[top] << _ << (int)tp[i] << '\n';
		/*for (re i = 1 ; i <= top ; ++ i)
			cerr << s[i] << _ << a[s[i]].belong << _ << a[s[i]].num << '\n';*/
		if (top == 0 or a[s[top]].belong != tp[i]){
			ider ++;
			s[++ top] = ider; a[s[top]] = (Kuai){tp[i], 1, 0}; ans[ider][++ ans[ider][0]] = i;
			// cerr << "↑if " << s[top] << _ << ider << _ << a[s[top]].num << _ << ans[s[top]][0] << '\n';
		}
		else {
			// cerr << "else↑" << '\n';
			a[s[top]].num ++; ans[s[top]][++ ans[s[top]][0]] = i;
			// cerr << s[top] << _ << a[s[top]].num << _ << ans[s[top]][0] << '\n';
			if (a[s[top]].num == 3){
				a[s[top]].tag = s[top-1]; du[s[top-1]] ++;
				top --;
			}
		}
		// Dl; Dl;
	}
	
	for (re i = 1 ; i <= ider ; ++ i){
		if (a[i].tag == 0 and a[i].belong == 0)// 出度不为0,否则他还限制别人
			pos[++ pos[0]] = i;
	}
	
	/*for (re i = 1 ; i <= ider ; ++ i)
		cerr << "SD " << ans[i][1] << _ << ans[i][2] << _ << ans[i][3] << _ << ans[i][4] << '\n';*/
	
	// cerr << pos[0] << '\n';
	
	int who = 1;
	for (re lun = 1 ; lun <= ider ; ++ lun){// 第几轮
		// cerr << who << '\n';
		for (re i = 1 ; i <= ider ; ++ i){// 选哪个
			if (lun < ider and a[i].belong == 0 and pos[0] == 1 and a[i].tag == 0)
				continue;
			if (vis[i] == true or a[i].belong != who or du[i] != 0)
				continue;
			vis[i] = true; du[a[i].tag] --;
			if (a[i].belong == 0 and a[i].tag == 0)
				pos[0] --;
			cout << ans[i][1] << _ << ans[i][2] << _ << ans[i][3] << '\n'; break;
		}
		who ^= 1;
	}
	
}
// #define IXINGMY
char_phi main(){
	#ifdef IXINGMY
		FBI_OPENTHEDOOR(a, a);
	#endif
	Fastio_setup();
	work();
	return GMY;
}
/*
2
2 3 4 9 10 11
0 1 1 1 0 0 0 0 1 1 1 0 
id 1 0 0 0 0
↑if 1 1 1 1


id 2 1 1 1 1
↑if 2 2 1 1


id 3 2 2 2 1
else↑
2 2 2


id 4 2 2 2 1
else↑
2 3 3


id 5 2 1 1 0
else↑
1 2 2


id 6 2 1 1 0
else↑
1 3 3


id 7 2 0 0 0
↑if 3 3 1 5


id 8 3 1 3 0
else↑
3 2 6


id 9 3 1 3 1
↑if 4 4 1 1


id 10 4 2 4 1
else↑
4 2 2


id 11 4 2 4 1
else↑
4 3 3


id 12 4 1 3 0
else↑
3 3 7


SD 1 5 6 2
SD 2 3 7 0
SD 0 0 3 9
SD 9 10 11 12
1 5 6
2 3 7
0 0 3
9 10 11
*/

/*
1 1 1 1 1 0 0 0 1 0  1  1  1  0  0  0  0  1  1  1  1  1  1  0  0  0  0  0  0  0
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
*/
posted @   char_phi  阅读(13)  评论(2编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示