首页 > 其他分享 >中值定理

中值定理

时间:2023-01-20 11:11:42浏览次数:38  
标签:二分 int 定理 个数 mid 考虑 EGF

模型:如果一个序列 \(a\) 长度为 \(p\),\(a_1 = 0, a_p = 1\),需要找到一个长度为 \(q\) 的子序列 \(a[l, r]\) 使得 \(a_l = 0, a_r = 1\),且 \(q|p\),那么可以这样考虑:对于 \([a_1,a_q],[a_{q+1},a_{2q}],[a_{2q+1},a_{3q}]...\) 一定存在至少一个序列满足条件。这是个可以二分的结构。二分的时候以 \(q\) 为单位长度,令 \(mid = kq\),若 \(a_{mid}=1\),那么继续在 \(a[l,mid]\) 上二分。否则在 \([mid+1,r]\) 上二分。

image

UER #11 B

【题意】给定一个长度为 \(2n-1\) 的序列,要求拿出其中的 \(n\) 个数,使得它们加起来是 \(n\) 的倍数。
\(n \le 5 \times 10^5\)
【分析】
令命题 \(EGF(n)\) 表示对于任意数组 \(n\) 都符合题意并且找到了一个构造方法。

若 \(n\) 为合数,不妨设 \(n=pq\)。假设 \(EGF(p) \and EGF(q)\),那么考虑首先对 \(n\) 不断取前 \(2p-1\) 个数,然后找出 \(p\) 个符合条件的数合并成一个 \(p\) 的倍数,再将其他数丢回去,直到剩下的数没有 \(2p-1\) 个为止。注意到 \(2n-1=2pq-1=(2q-2)p+(2p-1)\),因此可以找出 \((2q-1)\) 个 \(p\) 的倍数,剩下可以扔掉。然后对这些数做 \(EGF(q)\) 就得到了一组合法解。因此只需要考虑素数情形。

素数怎么办。考虑 \(EGF(p)\)。考虑对这 \(2p-1\) 个数采用不断选众数和第二多的数的方式,分成 \(p-1\) 个二元组和一个剩下来的数,其中每个二元组都满足其中两个数不一样。

我们选上这个数。另外选上每个二元组第一个数。得到一个 \(p\) 个数的选择方案,加起来为 \(k\)。我们的问题转化为了,有 \(p\) 个数 \(d_1,...,d_p\)(第二个数与第一个数的差),选出一个子集满足加起来模 \(p\) 余 \(-k\)。

先考虑证明一定存在一种选法。我们归纳地证明。

假设前 \(i\) 个数选出的子集和可以表出的数集合为 \(S_i\)。定义集合 \(S_i + k\) 表示 \(\{a+k|a\in S_i\}\)。那么考虑证明:\(k \not \equiv 0(\bmod p)\) 并且 \(S_i\) 不是 \(p\) 的完全剩余系的情况下 \(S_i \neq S_i+k\)。

这个怎么证,反证法。假设成立,那么考虑 \(x \in S_i, y \not \in S_i\) 有:\(x+k \in S_i, x+2k \in S_i,...\),但是我们令 \(j = (y-x) \times k^{-1}\),有 \(x+jk=y \in S_i\),矛盾。因此原命题成立。

这个命题代表了什么?\(S_i\) 不是 \(p\) 的完全剩余系的情况下 \(|S_i \cup (S_i+k)| > S_i\)!因此对于 \(S_0 = {0}\),\(S_n\) 一定是 \(p\) 的完全剩余系,因为每次会增长至少 \(1\) 个数。

我们考虑构造答案。首先我们让每次增长恰好 \(1\) 个数,则比较容易记录答案。暴力增长是 \(O(n^2)\) 的。我们考虑采用中值定理优化。

首先我们有个非常巧妙的观察:若 \(xk \in S_i, (x+1)k \not \in S_i\),那么一定可以将 \((x+1)k\) 放进去!并且你可以找到一个 \((u,v)\) 使得 \(uk \in S_i, vk \not \in S_i\)。因此可以直接中值定理二分,\(q=1\)。

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define f(i, a, b) for(int i = (a); i <= (b); i++)
#define cl(i, n) i.clear(),i.resize(n);
#define endl '\n'
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
const int inf = 1e9;
void cmax(int &x, int y) {if(x < y) x = y;}
void cmin(int &x, int y) {if(x > y) x = y;}
//调不出来给我对拍!
int a[700010];
bitset<300000> bs;
vector<int> v[300100];
set<pii> s;
pair<int, int> p;
int nsum = 0;
vector<int> ts;
vector<int> pre;
vector<int> add;
int tim[300100];
int ch[300100];
int n; 
int inv[300100];
int qpow(int x, int k) {
    int ans = 1;
    while(k) {
        if(k & 1) ans = ans * x % n;
        x = x * x % n;
        k >>= 1;
    }
    return ans;
}
int bin(int i, int j, int d) {
    int l = i * inv[d]; int r = j * inv[d] - 1;
    while(r < l) r += n;
    while(l < r) {  
        int mid = (l + r + 1) >> 1;
        if(!bs[mid * d % n]){r = mid - 1; }
        else { l = mid; }
    }
    return (r + 1) * d % n;
}
set<int> cp, uc;  //选了,没选  
signed main() {
    ios::sync_with_stdio(0);
    cin.tie(NULL);
    cout.tie(NULL);
    //time_t start = clock();
    //think twice,code once.
    //think once,debug forever.
    cin >> n;
    f(i, 1, n - 1) inv[i] = qpow(i, n - 2); 
    f(i, 1, 2 * n - 1) cin >> a[i];
    f(i, 1, 2 * n - 1) a[i] %= n;
    f(i, 1, 2 * n - 1) { v[a[i]].push_back(i); }
    f(i, 0, n - 1) { if(v[i].size() >= n) {f(j, 0, n - 1) {cout << v[i][j] << " ";} cout << endl; return 0;}}
    f(i, 0, n - 1) { s.insert({v[i].size(), i}); }
    ts.push_back(0); pre.push_back(0);
    f(i, 1, n - 1) {
        pii cur = (*(--s.end())); s.erase(--s.end());
        pii urc = (*(--s.end())); s.erase(--s.end());
    //    cout << cur.second << " " << urc.second << endl;
        nsum += cur.second; ch[cur.second] ++; nsum %= n; 
        ts.push_back((urc.second - cur.second + n) % n); pre.push_back(cur.second);
        if(cur.first > 1) {s.insert({cur.first - 1, cur.second});}
        if(urc.first > 1) {s.insert({urc.first - 1, urc.second});} 
    }
    pii nct = (*(--s.end()));// cout << nct.second << endl; //assert(s.size() == 1);
    nsum += nct.second; ch[nct.second] ++; nsum %= n; //cout << nsum << endl;
    int tar = (n - nsum) % n;

 //   cout << tar << endl;
    bs[0] = 1; tim[0] = 0;
    cp.insert(0); f(i, 1, n - 1) uc.insert(i);
    int now = 1;
    while(!bs[tar]) {
  //  f(i, 0, 3) {   
        int t = bin((*(cp.begin())), (*(uc.begin())), ts[now]);
        uc.erase(t); cp.insert(t);
        bs[t] = 1; tim[t] = now;
        
     //   cout <<"add : "<< t << endl;
     //   tim[t] = now; 
        now++;
 //   }
    }

    int ncp = tar; int ccp = tim[ncp];
    while(1) {
        if(ccp <= 0) break;
     //   cout << ncp << " " << ccp << endl;
        ch[pre[ccp]] --; ch[(pre[ccp] + ts[ccp]) % n] ++;
        ncp = (ncp - ts[ccp] + n) % n; ccp = tim[ncp];
    }
    f(i, 0, n - 1) { f(j, 0, ch[i] - 1) cout << v[i][j] << " ";}
    cout << endl;
    //time_t finish = clock();
    //cout << "time used:" << (finish-start) * 1.0 / CLOCKS_PER_SEC <<"s"<< endl;
    return 0;
}

[WC2023] 楼梯

也可以用中值定理优化 \(O(n^2)\) 的找区间子区间的过程,但是这题直接保证了 \(q|p\)。

标签:二分,int,定理,个数,mid,考虑,EGF
From: https://www.cnblogs.com/Zeardoe/p/17062547.html

相关文章

  • 线性空间的基本概念与定理1
    线性空间的基本概念与定理1.线性空间:给定集合$V$与数域$\mathbb{K}$,在$V$上定义加法运算$"+"$,以及数域$\mathbb{K}$与集合$V$之间的数乘运算,并要求上述加法运算满足交换......
  • 采样定理与SDMDM
    1.信噪比=6.02N+1.76dB对于这个经常引用的AD/DA转换器理论信噪比(SNR)公式,代表一个完美的N位ADC的理论性能。下面先计算N位模数转换器(ADC)的理论量化噪声。一旦通过计算均方根......
  • 算法学习笔记(9): 中国剩余定理(CRT)以及其扩展(EXCRT)
    扩展中国剩余定理讲解扩展之前,我们先叙述一下普通的中国剩余定理中国剩余定理中国剩余定理通过一种非常精巧的构造求出了一个可行解但是毕竟是构造,所以相对较复杂\[......
  • 扩展中国剩余定理
    学习扩展中国剩余定理前需要学习扩欧求逆元。\(\left\{\begin{matrix}x\equivc_{1}(\modm_{1})\\x\equivc_{2}(\modm_{2})\end{matrix}\right.\)\(x=c_{1}+m_{1}......
  • Codeforces 1630 E Making It Bipartite 题解 (Dilworth定理)
    题目链接首先可以想到把题目中的那张图G建出来,由于要求这张图是二分图,把它复制一遍(\(G\toG'\)),然后对于每个u,连一条无向边\(u-u'\),这样就变成了最大独立集问题。但是一......
  • Codeforces 1630 E Making It Bipartite 题解 (Dilworth定理)
    题目链接首先可以想到把题目中的那张图G建出来,由于要求这张图是二分图,把它复制一遍(\(G\toG'\)),然后对于每个u,连一条无向边\(u-u'\),这样就变成了最大独立集问题。但是一......
  • 环论中中国剩余定理证明笔记
    这一阵在看Maki的《抽象代数I》视频课(https://www.bilibili.com/video/BV1xG411j7Hk),其中第20课讲到环论的中国剩余定理,即:若(R,+,·)是交换环,Ii ◁R,i=1,...,......
  • [概率论与数理统计]笔记:3.5 大数定律与中心极限定理
    3.5大数定律与中心极限定理切比雪夫不等式定义\(EX\)和\(DX\)存在,对于任意的\(\epsilon>0\),有\[P\{|X-EX|\ge\epsilon\}\le\frac{DX}{\epsilon^2}\]证明这里证明\(......
  • P4980 【模板】Pólya 定理
    作为板子题,先上公式:\[|X/G|=\frac1{|G|}\sum_{g\inG}|B|^{c(g)}\]显然,\(|G|=n\)用\(g_i\)表示旋转\(i\)个的置换,则\(c(g_i)=(n,i)\)我们要算下式:\[\begin{ali......
  • 抽象代数:置换群,Burnside 引理和 Polya 定理
    群群的定义给定集合\(G\)和二元运算\(\cdot\)满足如下性质:封闭性:\(\foralla,b\inG\),有\((a\cdotb)\inG\)结合律:\(\foralla,b,c\inG\),有\((a\cdotb)\cdot......