2019nc#2

A Eddy Walker

題意

你有n個點(0~n-1),按順序造成一個環,初始時你在0的位子,你隨機順時針走一步或者逆時針走一步,node

一旦你走到一個點後,環上全部點都被通過至少一次後,你就必須停下來。ios

問你最後停留在m這個位子的機率是多少。c++

 注意輸出的答案是前綴積。數組

思路

有意思的機率題。ide

讀懂題意後發現這道題不難,模擬下能夠發如今最後落在(1~n-1)的位子是等機率的,落在0這個位子是不可能的(除非n==1)。優化

#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
#define pb push_back
#define fi first
#define se second
#define debug(x) cerr<<#x << " := " << x << endl;
#define bug cerr<<"-----------------------"<<endl;
#define FOR(a, b, c) for(int a = b; a <= c; ++ a)

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;


template<class T> void _R(T &x) { cin >> x; }
void _R(int &x) { scanf("%d", &x); }
void _R(ll &x) { scanf("%lld", &x); }
void _R(double &x) { scanf("%lf", &x); }
void _R(char &x) { scanf(" %c", &x); }
void _R(char *x) { scanf("%s", x); }
void R() {}
template<class T, class... U> void R(T &head, U &... tail) { _R(head); R(tail...); }


template<typename T>
inline T read(T&x){
    x=0;int f=0;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 x=f?-x:x;
}

const int inf = 0x3f3f3f3f;

const int mod = 1e9+7;

/**********showtime************/
            ll ksm(ll a, ll b) {
                ll res = 1;
                while(b > 0) {
                    if(b & 1) res = res * a % mod;
                    a = a * a % mod;
                    b = b >> 1;
                }
                return res;
            }
int main(){
            int T;  scanf("%d", &T);
            ll res = 1;
            while(T--){
                ll n,m;
                scanf("%lld%lld", &n, &m);
                if(n == 1 && m == 0) res = res;
                else {
                    if(m == 0) res = res * 0;
                    else {
                        res = res * ksm(n-1, mod-2) % mod;
                    }
                }
                printf("%lld\n", res);
            }

            return 0;
}
View Code

 B Eddy Walker 2

 BMspa

D Kth Minimum Clique

 題意:

 在一個無向圖中,找出一個權值爲第K小的最小團,最小團的定義爲選出的公共節點間有邊直接聯通。debug

 思路:

 感受實現起來不太難。既然要選擇第K小的,咱們能夠從小到大作。每次經過最小的一個最小團擴展,能夠利用bitset優化判斷擴展的可行性。3d

 即利用優先隊列,從其中取出的第k個就是答案。code

 有點像dji找最短路

#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define fi first
#define se second
#define debug(x) cerr<<#x << " := " << x << endl;
#define bug cerr<<"-----------------------"<<endl;
#define FOR(a, b, c) for(int a = b; a <= c; ++ a)
 
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
 
 
template<class T> void _R(T &x) { cin >> x; }
void _R(int &x) { scanf("%d", &x); }
void _R(ll &x) { scanf("%lld", &x); }
void _R(double &x) { scanf("%lf", &x); }
void _R(char &x) { scanf(" %c", &x); }
void _R(char *x) { scanf("%s", x); }
void R() {}
template<class T, class... U> void R(T &head, U &... tail) { _R(head); R(tail...); }
 
 
template<typename T>
inline T read(T&x){
    x=0;int f=0;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 x=f?-x:x;
}
 
const int inf = 0x3f3f3f3f;
 
const int mod = 1e9+7;
 
/**********showtime************/
 
            const int maxn = 109;
            char str[maxn];
            struct node{
                ll val;
                bitset<109>bs;
                bool operator<(const node & o) const{
                    return val > o.val;
                }
            }a[maxn];
int main(){
            int n,k;
            scanf("%d%d", &n, &k);
            for(int i=1; i<=n; i++) {
                scanf("%lld", &a[i].val);
            }
            for(int i=1; i<=n; i++) {
                scanf("%s", str+1);
                for(int j=1; j<=n; j++) {
                    if(str[j] == '1')a[i].bs.set(j);
                }
            } 
 
            priority_queue<node>que;
            node s;
            s.val = 0;
            s.bs.reset();
            que.push(s);
            int flag = 0;ll res;
            while(!que.empty()) {
                node u = que.top();
                que.pop();
                k -- ;
                if(k == 0) {
                    flag = 1;
                    res = u.val;
                    break;
                }
                int mx = 1;
                for(int i=1; i<=n; i++) {
                    if(u.bs[i] == 1) mx = i + 1;
                }
 
                for(int i=mx; i<=n; i++) {
                    if((u.bs & a[i].bs) == u.bs) {
                        u.bs.set(i);    u.val += a[i].val;
                        que.push(u);
                        u.bs.reset(i);    u.val -= a[i].val;
                    }
                }
            }
            if(flag) printf("%lld\n", res);
            else puts("-1");
            return 0;
}
View Code

 

E MAZE

線段樹,dp

F Partition problem

比賽時過的,雙向搜索下降複雜度(隊友搞的,我還沒搞)

I Inside A Rectangle

dp

H Second Large Rectangle

比賽時過的。DP出面積,找出次大的

(隊友搞的,我還沒搞)

J Subarray

題意:

有一個長度爲1E9,值爲{-1,1}的數組,保證只有n(<1e6)個區間等於1,且1的個數小於1e7。

求有多少對區間的區間和大於0。

思路:

首先把被答案區間所包含的點都找出來。最多隻有3e7個點。怎麼找?

從小到達遍歷數組,把每一個區間向右擴展的長度找出來,

從大到小遍歷數組,把每一個區間向左擴展的長度找出來。

 

而後計算每一個點的前綴和。在一個點前面且前綴和小於當前點的前綴和的一個點對應ans++。

因爲前綴和的變化大小爲1,因此不用樹狀數組便可完成。

#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define fi first
#define se second
#define debug(x) cerr<<#x << " := " << x << endl;
#define bug cerr<<"-----------------------"<<endl;
#define FOR(a, b, c) for(int a = b; a <= c; ++ a)

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;


template<class T> void _R(T &x) { cin >> x; }
void _R(int &x) { scanf("%d", &x); }
void _R(ll &x) { scanf("%lld", &x); }
void _R(double &x) { scanf("%lf", &x); }
void _R(char &x) { scanf(" %c", &x); }
void _R(char *x) { scanf("%s", x); }
void R() {}
template<class T, class... U> void R(T &head, U &... tail) { _R(head); R(tail...); }


template<typename T>
inline T read(T&x){
    x=0;int f=0;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 x=f?-x:x;
}

const int inf = 0x3f3f3f3f;
const ll inff = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9+7;

/**********showtime************/
            const int maxm = 2e7+9;
            const int maxn = 1e6+9;
            int le[maxn],ri[maxn];
            int lto[maxn],rto[maxn];
            ll f[maxm];
            int g(int x) {
                return x + 10000000;
            }
int main(){
            int n;
            scanf("%d", &n);

            for(int i=1; i<=n; i++) scanf("%d%d", &le[i], &ri[i]);

            int sum = 0;
            /// 向右擴展
            le[n+1] = 1000000000;
            for(int i=1; i<=n; i++) {
                sum += ri[i] - le[i] + 1;
                rto[i] = min(sum, le[i+1] - ri[i] - 1);
                sum -= le[i+1] - ri[i] - 1;
                if(sum < 0) sum = 0;
            }
            /// 向左擴展
            sum = 0;
            ri[0] = -1;

            for(int i=n; i>=1; i--) {
                sum += ri[i] - le[i] + 1;
                lto[i] = min(sum , le[i] - ri[i-1] -1);
                sum -= le[i] - ri[i-1] - 1;
                if(sum < 0) sum = 0;
            }

            ///計算每一個點的前綴和。lowsum保存前綴和比當前點小的個數
            ll  ans = 0, lowsum = 0;
            int s = 0, pos = 0;
            f[g(0)] = 1;
            for(int i=1; i<=n; i++) {

                for(int j=max(pos, le[i] - lto[i]); j<=ri[i] + rto[i]; j++) {

                    if(j>=le[i] && j <= ri[i]) {
                        lowsum += f[g(s)];
                        s++;
                        f[g(s)]++;
                        ans += lowsum;
                    }
                    else {
                        s--;
                        lowsum -= f[g(s)];
                        f[g(s)]++;
                        ans += lowsum;
                    }
//                    cout<<j<<" "<<lowsum<<endl;
                    pos = j+1;
                }
            }
//            cout<<endl;
            printf("%lld\n", ans);
            return 0;
}
View Code
本站公眾號
   歡迎關注本站公眾號,獲取更多信息