J A+B problem

签到 翻转之后相加 再翻转

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

int main() {
    int t;
    cin >> t;
    while(t--) {
        string a, b;
        cin >> a >> b;
        ll x = 0, y = 0;
        reverse(a.begin(), a.end());
        reverse(b.begin(), b.end());
        ll z = 0;
        for(int i = 0; i < a.size(); i++) {
            x = x * 10 + a[i] - '0';
        }
        for(int i = 0; i < b.size(); i++) {
            y = y * 10 + b[i] - '0';
        }
        z = x + y;
        if(!z)
            cout << z << endl;
        else {
            while(z % 10 == 0)
                z /= 10;
            while(z) {
                cout << z % 10;
                z /= 10;
            }
            cout << endl;
        }
    }
    return 0;
}

A String

分割 01 尽快让每段最长最小
最小表示 应该更快一些 不过 只有01 和长度才200

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

string s;

bool ok(int l, int r) {
    if(r == l)
        return 1;
    string ss = "";
    for(int i = l; i <= r; i++)
        ss += s[i];
    string str = ss;
    int x = r - l;
    while(x--) {
        str += str[0];
        str.erase(0, 1);
        if(str < ss)
            return 0;
    }
    return 1;
}

int main() {
    int t;
    cin >> t;
    while(t--) {
        cin >> s;
        int lr = s.size();
        int l = 0, r = lr - 1;
        while(1) {
            for(int i = r; i >= l; i--) {
                if(ok(l, i)) {
                    for(int j = l; j <= i; j++)
                        cout << s[j];
                    cout << ' ';
                    l = i + 1;
                    r = lr - 1;
                    break;
                }
            }
            if(l >= lr)
                break;
        }
        cout << endl;
    }
    return 0;
}

B Irreducible Polynomial

基本代数定理 除了 n == 2 无解没有的拆 >= 3 拆2项压力不打

#include<cstdio>
int main() {
    int n,tp,a[25];
    int cas;
    scanf("%d", &cas);
    while(cas --) {
        scanf("%d", &n);
        for(int i=0; i<=n; scanf("%d",a+i),i++);
        if(n>2||n==2&&a[1]*a[1]>=4*a[0]*a[2])
            printf("No\n");
        else
            printf("Yes\n");
    }
    return 0;
}

C Governing sand

权值线段树
我们 排好序 从小到大枚举 每次吧最小的多余的删掉 大于高度也去掉
枚举完 找最小值

#include <bits/stdc++.h>
#define fastio ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 5;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
typedef pair<int, int> P;

int n;
struct no {
    int h, c, p, pos;
} a[maxn];

bool cmp1(no a, no b) {
    return a.c < b.c;
}

bool cmp2(no a, no b) {
    return a.h < b.h;
}

struct node {
    ll num;
    ll sum;
} tree[maxn << 2];

void build(int l, int r, int rt) {
    tree[rt].num = 0;
    tree[rt].sum = 0;
    if (l == r)
        return;
    int mid = l + r >> 1;
    build(l, mid, rt << 1);
    build(mid + 1, r, rt << 1 | 1);
}

void updata(int L, int val, int num, int l, int r, int rt) {
    if (l == r) {
        tree[rt].num += num;
        tree[rt].sum += 1ll * num * val;
        return;
    }
    int mid = l + r >> 1;
    if(L <= mid)
        updata(L, val, num, l, mid, rt << 1);
    else
        updata(L, val, num, mid + 1, r, rt << 1 | 1);
    tree[rt].num = tree[rt << 1].num + tree[(rt << 1) | 1].num;
    tree[rt].sum = tree[rt << 1].sum + tree[(rt << 1) | 1].sum;
}

ll query(ll k, int l, int r, int rt) {
    if (k <= 0)
        return 0;
    if (k >= tree[rt].num)
        return tree[rt].sum;
    if (l == r) {
        return tree[rt].sum / tree[rt].num * k;
    }
    int mid = r + l >> 1;
    return query(k, l, mid, rt << 1) + query(k - tree[rt << 1].num, mid + 1, r, rt << 1 | 1);
}

signed main() {
    fastio;
    while (cin >> n) {
        ll ans = 0;
        for (int i = 1; i <= n; i++) {
            cin >> a[i].h >> a[i].c >> a[i].p;
            ans += (ll) a[i].c * a[i].p;
        }
        sort(a + 1, a + 1 + n, cmp1);
        for (int i = 0; i < n; i++)
            a[i].pos = i;
        build(1, n, 1);
        sort(a + 1, a + 1 + n, cmp2);

        int prep = 0;
        ll tot = 0;
        ll cnt = a[1].p;
        ll res = ans - 1ll * a[1].p * a[1].c;
        for (int i = 2; i <= n; i++) {
            if (i == n + 1 || a[i].h != a[i - 1].h) {
                ll tmp =  query(tot - (cnt - 1), 1, n, 1) + res;
                if (ans > tmp) ans = tmp;
                cnt = a[i].p;
                while (prep < i) {
                    updata(a[prep].pos, a[prep].c, a[prep].p, 1, n, 1);
                    tot += a[prep].p;
                    prep++;
                }
            } else cnt += a[i].p;
            
            res -= (ll)a[i].c * a[i].p;
        }
        cout << ans << endl;
    }
    return 0;
}

D Number

找个n位 p 的倍数 补0 。。。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2e5 + 5;
const int INF = 0x3f3f3f3f;
const long long LINF = 0x3f3f3f3f3f3f3f3f;
typedef pair<int, int> P;

int main() {
	string p;
	int n;
	cin >> n >> p; 
	int lenn = n;
	int lenp = p.size();
	
	if(lenn == lenp ) cout << p << endl;
	else if(lenn < lenp) cout << "T_T" << endl;
	else {
		cout << p ;
		for(int i = 1; i <= lenn - lenp; i ++) {
			cout << 0;
		}cout << endl;
	}
	
	return 0;
}

E Find the median

这道题
首先 我们把能想到线段树 其次 维护 这一片区间 + 1的次数
那么就是 用点代表区间
如果我们考虑用点 代表区间的话 首先我们对这个区间进行一个补长 右边加个一什么的
(5, 6) (7, 9) (9, 11) (11, 11)
我们 左端点不变 右端点 +1 进行离散化前存储
然后 离散化完 我们实际存储
第一 5, 6 区间 被我们 [1, 2)
第二 7, 9 区间 被我们 [2, 4)
第三 9, 11 区间 被我们 [ 3, 6)
第4区间 11 11 被我们 [5, 6) 代替了
这样 左开右闭区间 就能 一个不拉处理他们

如果 我们处理 5, 6 区间 我们只要 直接查 左区间 下标 (右区间 + 1)(我们离散化 + 1 就是为了能不重复的处理区间 这里要补回1)下标 - 1 相当于 第一个区间 1 这个点代表了 5 【2,4)这个区间 代表了7,9
数据差多大 都可以用这样处理的下标 不漏不重的处理

#include <bits/stdc++.h>
#define fastio ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
typedef long long ll;
const int maxn = 4e5 + 10;
int le[maxn], rig[maxn];
int n;
int a1, a2, b1, b2, x[maxn], y[maxn], c1, c2, m1, m2;
int b[maxn << 1], ls[maxn], rs[maxn];
ll sum[maxn << 3], lazy[maxn << 3];
 
void push_down(int l, int r, int root) {
    if(!lazy[root])
        return ;
    int mid = l + r >> 1;
    sum[root << 1] += (ll)(b[mid + 1] - b[l]) * lazy[root];
    sum[root << 1 | 1] += (ll)(b[r + 1] - b[mid + 1]) * lazy[root];
    lazy[root << 1] += lazy[root];
    lazy[root << 1 | 1] += lazy[root];
    lazy[root] = 0;
}
 
void updata(int L, int R, int l, int r, int rt) {
    if(L <= l && R >= r) {
        lazy[rt] += 1;
        sum[rt] += 1ll * (b[r + 1] - b[l]);
        return ;
    }
    push_down(l, r, rt);
    int mid = l + r >> 1;
    if(L <= mid)
        updata(L, R, l, mid, rt << 1);
    if(R > mid)
        updata(L, R, mid + 1, r, rt << 1 | 1);
    sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
}
 
int query(int l, int r, int rt, ll k) {
    if(l == r)
        return b[l] + (k - 1) / (lazy[rt]); // sum 和 lazy 最后不一样 sum 是这一段所有的和 lazy 只是次数
    int mid = l + r >> 1;
    push_down(l, r, rt);
    if(sum[rt << 1] < k)
        return query(mid + 1, r, rt << 1 | 1, k - sum[rt << 1]);
    else
        return query(l, mid, rt << 1, k);
}
 
signed main() {
    fastio;
    cin >> n;
    cin >> x[1] >> x[2] >> a1 >> b1 >> c1 >> m1;
    cin >> y[1] >> y[2] >> a2 >> b2 >> c2 >> m2;
 
    int len = 0;
    for(int i = 3; i <= n; i ++) {
        x[i] = (1ll * a1 * x[i - 1] + b1 * x[i - 2] + c1) % m1;
        y[i] = (1ll * a2 * y[i - 1] + b2 * y[i - 2] + c2) % m2;
    }
 
    for(int i = 1; i <= n; i ++) {
        ls[i] = min(x[i], y[i]) + 1;
        b[++ len] = ls[i];
        rs[i] = max(x[i], y[i]) + 1;
        b[++ len] = rs[i] + 1;
    }
    sort(b + 1, b + 1 + len);
    len = unique(b + 1, b + 1 + len) - b - 1;
    ll tot = 0;
    for(int i = 1; i <= n; i ++) {
        tot += (rs[i] - ls[i] + 1);
        int ul = lower_bound(b + 1, b + 1 + len, ls[i]) - b;
        int ur = lower_bound(b + 1, b + 1 + len, rs[i] + 1) - b;
        updata(ul, ur - 1, 1, len, 1);
        cout << query(1, len, 1, (tot + 1) / 2) << endl;
    }
    return 0;
}