QBXT2025S刷题 Day5

今天更废了。
\(30pts\ rk84\)
今天的题

T1

机房大部分人都做出来了,可是我只是打了个暴力(还没拿分)。
这道题其实可以把 \((b_1,b_2,b_3,b_4)\) 分为 \((b_1,b_2),(b_3,b_4)\) 两个部分。
这样的话,我们就可以开一个桶,然后存 \(a_{b_1}\oplus a_{b_2}\)
因为这个 \(b_1,b_2,b_3,b_4\) 是单调递增的,所以我们可以从左到右枚举一个中间点,统计后面的点,存左面的点,这样不会重复。

#include <iostream>

using std::cin;
using std::cout;
const int N = (int)2e6 + 10;

int a[N];
int cnt[N];

int main()
{
	int n;
	cin >> n;
	for (int i = 1; i <= n; ++i)
		cin >> a[i];
	long long ans = 0;
	for (int i = 1; i <= n; ++i)
	{
		for (int j = i + 1; j <= n; ++j)
			ans += cnt[a[i] ^ a[j]];
		for (int j = 1; j <= i - 1; ++j)
			cnt[a[i] ^ a[j]]++;
	}
	cout << ans << '\n';
	return 0;
}

T2

死了,\(30pts\)
假设某个数对应的是 \(0\)
那么这个数很容易观察出来,因为这一行将都是 \(0\)
然后考虑 \(p - 1\)
那么 \([1,p - 1]\),分别乘 \(p - 1\),就会是 \((0,p - 1),(1, p - 2)\dots\),他们的高位是互不相同的,且只有 \(p - 1\) 这样。
然后经过观察十进制的九九乘法表可以得到,如果第 \(i\) 行的高位有多少不同的数,那么 \(i\) 对应的数,就是这个数。

#include <iostream>
#include <cstring>

using std::cin;
using std::cout;
const int N = 2010;

int p;
int cnt;
int cn[N];
int re[N];
int ans[N];
int vis[N][N];
int a[N][N << 1];

void read(int &x)
{
	x = 0;
	char c = getchar();
	int f = 1;
	while (!isdigit(c))
	{
		if (c == '-')
			f = -f;
		c - getchar();
	}
	while (isdigit(c))
	{
		x = x * 10 + c - '0';
		c = getchar();
	}
	x = x * f;
}

int main()
{
	read(p);
	for (int i = 1; i <= p; ++i)
	{
		for (int j = 1; j <= p; ++j)
		{
			read(a[i][2 * j - 1]);
			read(a[i][2 * j]);
			cn[a[i][2 * j - 1]]++;
			cn[a[i][2 * j]]++;
		}
	}
	int max = cn[0];
	int idx = 0;
	for (int i = 0; i < p; ++i)
	{
		if (cn[i] > max)
		{
			idx = i;
			max = cn[i];
		}
	}
	ans[0] = idx;
	memset(cn, 0, sizeof(cn));
	for (int i = 1; i <= p; ++i)
	{
		for (int j = 1; j <= p; ++j)
		{
			if (!vis[i][a[i][2 * j - 1]])
			{
				cn[i]++;
				vis[i][a[i][2 * j - 1]] = true;
			}
		}
		if (cn[i] == 1)
		{
			if (ans[0] != i - 1)
				ans[1] = i - 1;
		}
		else
			ans[cn[i]] = i - 1;
	}
	for (int i = 0; i <= p - 1; ++i)
		re[ans[i]] = i;
	for (int i = 0; i <= p - 1; ++i)
		cout << re[i] << ' ';
	cout << '\n';
	return 0;
}

T3

死了。
Pasted image 20251006211428

#include<bits/stdc++.h>
#define IL inline
#define reg register
#define N 200200
#define int long long
#define mod 1000000007
#define oo (1ll<<60)
#define getchar()(inBuf==lenBuf?lenBuf=(inBuf=Buf)+fread(Buf,1,1<<20,stdin):0,inBuf==lenBuf?EOF:*inBuf++)
char Buf[1<<20],*inBuf,*lenBuf;
IL int read()
{
    reg int x=0,f=0; reg char ch=getchar();
    while(ch<'0'||ch>'9')f|=ch=='-',ch=getchar();
    while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    return f?-x:x;
}

IL int Add(reg int x,reg int y){return x+y<mod?x+y:x+y-mod;}
IL int Sub(reg int x,reg int y){return x<y?x-y+mod:x-y;}
IL void Pls(reg int &x,reg int y){x=Add(x,y);}
IL void Dec(reg int &x,reg int y){x=Sub(x,y);}
IL int Mul(reg int x,reg int y){reg int r=x*y; return r<mod?r:r%mod;}

int n,a[3][N],ans;
int dl[3][3][N],dr[3][3][N],d[3][3][N];

IL bool cmin(reg int &x,reg int y){return x>y?x=y,1:0;}

struct Node
{
    int x,y,w;
    IL bool operator <(const Node &a)const{return w>a.w;}
};

const int dx[]={0,1,0,-1},dy[]={1,0,-1,0};
int dis[3][N];

void dijkstra(reg int p,reg int l,reg int r)
{
    for(reg int o=0,i,j;o<3;++o)
    {
        for(i=0;i<3;++i)for(j=l;j<=r;++j)dis[i][j]=oo;
        dis[o][p]=a[o][p];
        for(j=l;j<=r;++j)
        {
            if(j>l)for(i=3;i--;)cmin(dis[i][j],dis[i][j-1]+a[i][j]);
            for(i=1;i<3;++i)cmin(dis[i][j],dis[i-1][j]+a[i][j]);
            for(i=2;i--;)cmin(dis[i][j],dis[i+1][j]+a[i][j]);
        }
        for(j=r;j>=l;--j)
        {
            if(j<r)for(i=3;i--;)cmin(dis[i][j],dis[i][j+1]+a[i][j]);
            for(i=1;i<3;++i)cmin(dis[i][j],dis[i-1][j]+a[i][j]);
            for(i=2;i--;)cmin(dis[i][j],dis[i+1][j]+a[i][j]);
        }
        for(j=l;j<=r;++j)
        {
            if(j>l)for(i=3;i--;)cmin(dis[i][j],dis[i][j-1]+a[i][j]);
            for(i=1;i<3;++i)cmin(dis[i][j],dis[i-1][j]+a[i][j]);
            for(i=2;i--;)cmin(dis[i][j],dis[i+1][j]+a[i][j]);
        }
        for(i=0;i<3;++i)for(j=l;j<=r;++j)
            d[o][i][j]=dis[i][j];
    }
}

int ys[N*6],len;

struct Point
{
    int x,y,d;
    IL bool operator <(const Point &a)const{return x<a.x;}
}p[N*3],q[N*3];

struct Bit
{
    int c[N*6];
    IL void clear(){std::fill(c+1,c+1+len,0);}
    IL int low(reg int x){return x&-x;}
    IL int ask(reg int x){reg int r=0; for(;x;x-=low(x))Pls(r,c[x]); return r;}
    IL void add(reg int x,reg int k){for(;x<=len;x+=low(x))Pls(c[x],k);}    
}A,B;

void cdq(reg int l,reg int r)
{
    if(l==r)
    {
        for(reg int i=0,j;i<3;++i)for(j=0;j<i;++j)
            Pls(ans,dl[i][j][l]%mod);
        return;
    }
    reg int mid=l+r>>1;
    dijkstra(mid,l,r);
    for(reg int o=0,i,j,k;o<3;++o)for(k=0;k<3;++k)for(i=0;i<3;++i)for(j=l;j<=mid;++j)
    {
        cmin(d[o][i][j],dl[k][i][j]+dl[k][o][mid]-a[k][l]);
        cmin(d[o][i][j],dr[k][i][j]+dr[k][o][mid]-a[k][r]);
    }
    for(reg int o=0,i,j;o<3;++o)for(i=0;i<3;++i)for(j=l;j<=mid;++j)
        dr[o][i][j]=d[o][i][j];

    dijkstra(mid+1,l,r);
    for(reg int o=0,i,j,k;o<3;++o)for(k=0;k<3;++k)for(i=0;i<3;++i)for(j=mid+1;j<=r;++j)
    {
        cmin(d[o][i][j],dl[k][i][j]+dl[k][o][mid+1]-a[k][l]);
        cmin(d[o][i][j],dr[k][i][j]+dr[k][o][mid+1]-a[k][r]);
    }
    for(reg int o=0,i,j;o<3;++o)for(i=0;i<3;++i)for(j=mid+1;j<=r;++j)
        dl[o][i][j]=d[o][i][j];

    static int id[3][N];
    for(reg int u=0,v,o,i,j,x,cnt;u<3;++u)
    {
        len=cnt=0;
        reg int ti=0,tj=0;
        for(o=0;o<3;++o)for(i=l;i<=mid;++i)
            id[o][i]=++ti,p[ti].d=dr[u][o][i]%mod;
        for(o=0;o<3;++o)for(i=mid+1;i<=r;++i)
            id[o][i]=++tj,q[tj].d=dl[u][o][i]%mod;
        for(v=0;v<3;++v)if(u!=v)
        {
            ++cnt;
            for(o=0;o<3;++o)for(i=l;i<=mid;++i)
            {
                x=id[o][i];
                if(cnt==1)p[x].x=dr[v][o][i]-dr[u][o][i]-(u>v);
                else ys[++len]=p[x].y=dr[v][o][i]-dr[u][o][i]-(u>v);
            }
            for(o=0;o<3;++o)for(i=mid+1;i<=r;++i)
            {
                x=id[o][i];
                if(cnt==1)q[x].x=dl[u][o][i]-dl[v][o][i];
                else ys[++len]=q[x].y=dl[u][o][i]-dl[v][o][i];
            }
        }
        std::sort(ys+1,ys+1+len),len=std::unique(ys+1,ys+1+len)-ys-1;
        for(i=1;i<=ti;++i)p[i].y=std::lower_bound(ys+1,ys+1+len,p[i].y)-ys;
        for(i=1;i<=tj;++i)q[i].y=std::lower_bound(ys+1,ys+1+len,q[i].y)-ys;
        std::sort(p+1,p+1+ti),std::sort(q+1,q+1+tj);
        A.clear(),B.clear();
        for(i=j=1;i<=ti;++i)
        {
            while(j<=tj&&q[j].x<=p[i].x)
                A.add(q[j].y,1),B.add(q[j].y,q[j].d),++j;
            Pls(ans,Mul(A.ask(p[i].y),p[i].d)),Pls(ans,B.ask(p[i].y));
        }
    }
    cdq(l,mid),cdq(mid+1,r);
}

main()
{
    n=read();
    for(reg int i=0,j;i<3;++i)for(j=1;j<=n;++j)a[i][j]=read();
    dijkstra(1,1,n);
    for(reg int o=0,i,j;o<3;++o)for(i=0;i<3;++i)
        for(j=1;j<=n;++j)dl[o][i][j]=d[o][i][j];
    dijkstra(n,1,n);
    for(reg int o=0,i,j;o<3;++o)for(i=0;i<3;++i)
        for(j=1;j<=n;++j)dr[o][i][j]=d[o][i][j];    
    cdq(1,n),printf("%lld\n",Mul(ans,2));
}

T4

死了。
假设我们只要求最大值。
Pasted image 20251006211607

#define WANT_LDEBUG
// #define LDEBUG_TO_ERR_TXT
// #define CALC_TIME
// #define CALC_MEM

#ifdef CALC_MEM
bool m_be_;
#endif
#ifdef LOCAL
#include "D:/Code/C++/include/all.h"
#else
#include <bits/stdc++.h>
#define INCLUDED_ALL
#define ldebug(...) []() {}()
#define fast_io()                                                              \
    std::ios::sync_with_stdio(false);                                          \
    std::cin.tie(nullptr)
#endif
using namespace std;
using i8 = signed char;
using i16 = short;
using i32 = int;
using i64 = long long;
using i128 = __int128;
using u8 = unsigned char;
using u16 = unsigned short;
using ui = unsigned int;
using u64 = unsigned long long;
using u128 = unsigned __int128;
using f64 = double;
using f96 = long double;
template <typename T, size_t F, size_t... Args> class mdarray {
  private:
    std::array<mdarray<T, Args...>, F> a;

  public:
    mdarray<T, Args...> &operator[](size_t i) { return a[i]; }
    const mdarray<T, Args...> &operator[](size_t i) const { return a[i]; }
};
template <typename T, size_t F> class mdarray<T, F> {
  private:
    std::array<T, F> a;

  public:
    T &operator[](size_t i) { return a[i]; }
    const T &operator[](size_t i) const { return a[i]; }
};
template <typename T, typename U> bool ckmax(T &a, const U &b) {
    return a < b && (a = b, true);
}
template <typename T, typename U> bool ckmin(T &a, const U &b) {
    return b < a && (a = b, true);
}
#ifdef CALC_TIME
auto t_be_ = std::chrono::high_resolution_clock::now();
#endif

// ===== program begin ======

constexpr u64 MOD = 1e9 + 7;
u64 adj(u64 a) { return a >= MOD ? a - MOD : a; }
void pls_eq(u64 &a, const u64 b) { a = adj(a + b); }
constexpr ui MAXN = 605, MAXK = 20;
ui N, K;
array<ui, MAXN> a;
struct Way {
    array<pair<int, u64>, MAXK> a;
    ui n;
    pair<int, u64> &operator[](size_t k) { return a[k]; }
    const pair<int, u64> &operator[](size_t k) const { return a[k]; }
};
array<array<array<array<Way, 2>, 2>, MAXN>, MAXN> dp;

bool mode;
void merge_array(Way &a, const Way &b, int add, u64 mul) {
    if (a.n + b.n == 0 || mul == 0) {
        return;
    }
    static Way c;
    c.n = 0;
    ui pa = 0, pb = 0;
    while (pa < a.n && pb < b.n) {
        if (a[pa].first == b[pb].first + add) {
            c[c.n++] = make_pair(a[pa].first,
                                 adj(a[pa].second + b[pb].second * mul % MOD));
            ++pa;
            ++pb;
        } else if (a[pa].first > b[pb].first + add) {
            c[c.n++] = a[pa++];
        } else {
            c[c.n++] = make_pair(b[pb].first + add, b[pb].second * mul % MOD);
            ++pb;
        }
        if (c.n == K) {
            break;
        }
    }
    while (pa < a.n && c.n < K) {
        c[c.n++] = a[pa++];
    }
    while (pb < b.n && c.n < K) {
        c[c.n++] = make_pair(b[pb].first + add, b[pb].second * mul % MOD);
        ++pb;
    }
    // if (mode && find(c.a.begin(), c.a.begin() + c.n, make_pair(-1, 1ULL)) != c.a.begin() + c.n) {
    //     ldebug("Here\n");
    // }
    a = c;
}
void test_case() {
    cin >> N >> K;
    for (ui i = 0; i < N; ++i) {
        cin >> a[i];
    }
    sort(a.begin(), a.begin() + N);
    dp[1][1][0][0][dp[1][1][0][0].n++] = make_pair(-a[0] * 2, 1);
    dp[1][1][0][1][dp[1][1][0][1].n++] = make_pair(-a[0], 1);
    dp[1][1][1][0][dp[1][1][1][0].n++] = make_pair(-a[0], 1);
    for (ui i = 1; i < N; ++i) {
        mode = (i == 3);
        for (ui j = 1; j <= i; ++j) {
            // for (ui k = 0; k < 2; ++k) {
            //     for (ui l = 0; l < 2; ++l) {
            //         ldebug("dp[{},{},{},{}]:{}", i, j, k, l, dp[i][j][k][l].n);
            //         for (ui m = 0; m < dp[i][j][k][l].n; ++m) {
            //             ldebug("<{},{}>", dp[i][j][k][l][m].first,
            //                    dp[i][j][k][l][m].second);
            //         }
            //         ldebug("\n");
            //     }
            // }
            // 1. 新开一段
            // 1.1 头
            merge_array(dp[i + 1][j + 1][1][0], dp[i][j][0][0], -a[i], 1);
            merge_array(dp[i + 1][j + 1][1][1], dp[i][j][0][1], -a[i], 1);
            // 1.2 尾
            merge_array(dp[i + 1][j + 1][0][1], dp[i][j][0][0], -a[i], 1);
            merge_array(dp[i + 1][j + 1][1][1], dp[i][j][1][0], -a[i], 1);
            // 1.3 中间
            merge_array(dp[i + 1][j + 1][0][0], dp[i][j][0][0], -a[i] * 2,
                        j + 1);
            merge_array(dp[i + 1][j + 1][0][1], dp[i][j][0][1], -a[i] * 2, j);
            merge_array(dp[i + 1][j + 1][1][0], dp[i][j][1][0], -a[i] * 2, j);
            if (j > 1) {
                merge_array(dp[i + 1][j + 1][1][1], dp[i][j][1][1], -a[i] * 2,
                            j - 1);
            }

            // 2. 扩展连续段
            // 2.1 [0][0]
            merge_array(dp[i + 1][j][0][0], dp[i][j][0][0], 0, j * 2);
            merge_array(dp[i + 1][j][1][0], dp[i][j][0][0], a[i], 1);
            merge_array(dp[i + 1][j][0][1], dp[i][j][0][0], a[i], 1);
            // 2.2 [0][1]
            merge_array(dp[i + 1][j][0][1], dp[i][j][0][1], 0, j * 2 - 1);
            merge_array(dp[i + 1][j][1][1], dp[i][j][0][1], a[i], 1);
            // 2.3 [1][0]
            merge_array(dp[i + 1][j][1][0], dp[i][j][1][0], 0, j * 2 - 1);
            merge_array(dp[i + 1][j][1][1], dp[i][j][1][0], a[i], 1);
            // 2.4 [1][1]
            if (j > 1) {
                merge_array(dp[i + 1][j][1][1], dp[i][j][1][1], 0, j * 2 - 2);
            }

            if (j > 1) {
                // 3. 合并连续段
                merge_array(dp[i + 1][j - 1][0][0], dp[i][j][0][0], a[i] * 2,
                            j - 1);
                merge_array(dp[i + 1][j - 1][0][1], dp[i][j][0][1], a[i] * 2,
                            j - 1);
                merge_array(dp[i + 1][j - 1][1][0], dp[i][j][1][0], a[i] * 2,
                            j - 1);
                merge_array(dp[i + 1][j - 1][1][1], dp[i][j][1][1], a[i] * 2,
                            j - 1);
            }
        }
    }
    for (ui i = 0; i < K; ++i) {
        if (i >= dp[N][1][1][1].n) {
            cout << "-1 -1\n";
        } else {
            cout << dp[N][1][1][1][i].first << " " << dp[N][1][1][1][i].second
                 << "\n";
        }
    }
}

// ===== program end =====

#ifdef CALC_MEM
bool m_en_;
#endif
int main(int, char **) {
    fast_io();
#ifdef CALC_MEM
    cerr << llabs(&m_be_ - &m_en_) / 1048576.0 << "MB\n";
#endif
    // init();
    ui T = 1;
    // cin >> T;
    while (T--) {
        test_case();
#ifdef DEBUG
        cerr << endl;
#endif
    }
#ifdef CALC_TIME
    auto t_en_ = std::chrono::high_resolution_clock::now();
    cerr << std::chrono::duration_cast<std::chrono::milliseconds>(t_en_ - t_be_)
                .count()
         << "ms\n"
#endif
        return 0;
}

posted @ 2025-10-06 21:18  SigmaToT  阅读(8)  评论(0)    收藏  举报