1. 程式人生 > >清北學堂國慶day7解題報告

清北學堂國慶day7解題報告

情況 kth esp 樹狀數組 錯誤分析 family 題目 ostream stream

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解題報告