清北学堂国庆day7解题报告

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了清北学堂国庆day7解题报告相关的知识,希望对你有一定的参考价值。

day7解题报告

张炳琪

时间安排::

T1:60分钟

T2:40分钟

T340分钟

答题情况和错误分析::

T1 60

得了暴力分,有另外二十分其实还是有机会拿的,没有仔细再看看想想

T280

拿了80分的暴力分,正解没有想出来

T360

还是打了60的暴力分,正解难写 

Tot::200

题目解析:

T1

先用dfs枚举出所有状态,然后用容斥原理求解.刚开始用数组记录不太好记后来发现直接加就可以(坑点是中途会炸数据范围,gcd都会炸)

T2

我的暴力是维护两个堆来维护区间中位数,然后n^2枚举区间

正解是考虑每个位置上数字的影响 

a[i]为前i个数中有a[i]个数>=t,若奇数区间[l,r]的中位数>=t,则(a[r]-a[l-1])*2>r-l+1,(a[r]*2-r)>(a[l-1]*2-l+1)

然后枚举加二分统计,总复杂度nlog2n

T3

k大的值用二分去找,然后统计贡献用线段树维护,或者用树状数组维护,

代码:

T1:

#include<cstdio>
#include<algorithm>
#include<iostream>
#define MAXN 1001000
#define ll long long
using namespace std;
bool visited[MAXN];
int note[123546];
int n,m; 
long long T = n;
ll fan(ll x)
{
    return -x;
}
ll gcd(ll a,ll b)
{
    return b == 0 ? a : gcd(b,a % b);
}
ll lcm(ll a,ll b)
{
    return a * b / gcd(a,b);
}

void dfs(int step,int xuan,long long LCM)
{
    if(LCM > n)return;
    if(step == m + 1)
    {
        if(xuan & 1)T -= n / LCM;
        else T += n /LCM;
        return;
    }
    dfs(step + 1,xuan + 1,lcm(LCM,note[step]));
    dfs(step + 1,xuan,LCM);
}

int main()
{
    freopen("count.in","r",stdin);freopen("count.out","w",stdout);
    scanf("%d%d",&n,&m);
    for(int i = 1;i <= m;i++)
        scanf("%d",&note[i]);
    dfs(1,0,1);
    cout << T;
    return 0;
}
/*
100000 5
2  4 6 8 9
100000 20
123
56
23
94
2
6
8
53
76
95
18
27
99
101
102
103
104
105
999
3569
*/

 

T2:

#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
long long a[123123];
long long b[123123];
long long c[123123];
long long d[123123];
long long e[123123];
long long n,m,k;

long long lowbit(long long x)
{
    return x & (-x);
}

long long add(long long x)
{
    while(x<=m)e[x]++,x += lowbit(x);
}

long long find(long long x)
{
    int ans = 0;
    while(x)ans += e[x],x -= lowbit(x);
    return ans;
}

long long erfen(long long x)
{
    int l = 1,r = m;
    while(l < r)
    {
        int mid = (l + r) >> 1;
        if(x <= d[mid])r = mid;
        else l = mid + 1;
    }
    return l;
}

long long  check(long long x)
{
    c[0] = 0;
    for(int i = 1;i <= n;i++)c[i] = c[i - 1] + (a[i] >= x);
    for(int i = 0;i <= n;i++)c[i] = c[i] * 2 - i,d[i + 1] = c[i];
    sort(d + 1,d + n + 2);
    d[0] = 1;
    for(int i = 2;i <= n + 1;i++)
        if(d[i] != d[d[0]])d[++d[0]] = d[i];
    m = d[0];
    long long ans = 0;
    for(int i = 0;i <= n;i++)c[i] = erfen(c[i]);
    for(int i = 0;i <= m;i++)e[i] = 0;
    for(int i = 0;i <= n;i++)
        if(i & 1)add(c[i]);
        else ans += find(c[i] - 1);
    for(int i = 0;i <= m;i++)e[i] = 0;
    for(int i = 0;i <= m;i++)
        if((i&1) == 0)add(c[i]);
        else ans += find(c[i] - 1);
    return ans; 
}




int main()
{
    freopen("kth.in","r",stdin);freopen("kth.out","w",stdout);
    cin >> n >> k;
    for(int i = 1;i <= n;i++)cin >> a[i],b[i] = a[i];
    sort(b + 1,b + n + 1);
    b[0] = 1;
    for(int i = 2;i <= n;i++)
        if(b[i] != b[b[0]])b[++b[0]] = b[i];    
    int l = 1,r = b[0];
    while(l < r){
        int mid = (l + r) / 2 + 1;
        long long tt = check(b[mid]);
        if(tt == k)
        {
            cout << b[mid];
            return 0;
        }
        if(check(b[mid]) > k)l = mid;
        else r = mid - 1;
    }
    cout << b[l];
    return 0;
}

T3:

#include<cstdio>
#include<algorithm>
#include<iostream>
#define mod 1000000007 
using namespace std;
int n;
struct Note{
    int ID;
    int num;
}note[1234567];
long long A,B,C;

int c1[1234567];
int c2[1234567]; 

bool cmp (Note a,Note b)
{
    return a.num < b.num;
}

int lowbit(int x)
{
    return x &(-x);
}

int find(int *c,int x)
{
    int ans = 0;
    while(x)
    {
        ans = (ans + c[x]) % mod;
        x -= lowbit(x);
    }
    return ans;
}

void add(int *c,int x,int ver)
{
    c[0] += ver;
    c[0] %= mod;
    while(x <= n)
    {
        c[x] += ver;
        c[x] %= mod;
        x += lowbit(x);
    }
}

int main()
{
    freopen("sum.in","r",stdin);freopen("sum.out","w",stdout);
    cin >> n >> note[1].num >> A >> B >> C;note[1].ID = 1;
    for(int i = 2;i <= n;i++)note[i].num = (note[i - 1].num * A + B) % C,note[i].ID = i;
    
    sort(note + 1,note + n + 1,cmp);
    long long ans = 0;
    for(int i = 1;i <= n;i++)
    {
        int t1 = find(c1,note[i].ID);
        int t2 =( c2[0] - find(c2,note[i].ID - 1) + mod) % mod;
        
        int t3 = (1ll * t1 * (n - note[i].ID + 1) + 1ll * t2 * note[i].ID) % mod;
        t3 = (t3 + 1ll * note[i].ID *(n - note[i].ID + 1)) % mod;
        
        ans = (ans + 1ll * t3  * note[i].num) % mod;
        add(c1,note[i].ID,note[i].ID);
        add(c2,note[i].ID,n - note[i].ID + 1);
    }    
    cout << ans << endl;
    return 0;
}

 

以上是关于清北学堂国庆day7解题报告的主要内容,如果未能解决你的问题,请参考以下文章

清北学堂国庆day1解题报告

清北学堂国庆day6解题报告

清北学堂国庆day5解题报告

清北学堂国庆day3解题报告

清北学堂国庆day4解题报告

2017.7.21夏令营清北学堂解题报告