程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> Codeforces398D Instant Messanger

Codeforces398D Instant Messanger

編輯:C++入門知識

題目鏈接


是的真相就是耍流氓暴力!!!

離線處理

處理出每個點的點度deg[i](無重邊)

維護一個數組from_small[i],表示與i相鄰的點中點度比deg[i]小的點的在線數量

然後對於每個詢問,暴力數出i的相鄰點中點度比deg[i]大的點在線的數量,然後加上from_small[i],就是答案

復雜度是O(操作數*sqrt(點度之和))

證明:

每次詢問的復雜度為O(1) + O(遍歷度數比deg[i]大的鄰點)

設度數比deg[i]大的鄰點有x個

此時有deg[i] >= x

所以i和他的鄰點度數和至少為x*(x+1),

因為 sigma(deg[i]) <= 2*E (E為不重疊的邊數)

所以滿足deg[j] >= deg[i]的鄰點的個數最多為sqrt(2*E)

證畢

然後其他操作的復雜度也類似,此處略過

#include 
#include 
#include 
#include 
using namespace std;

#define snuke(it,x) for (__typeof((x).begin()) it = (x).begin(); \
                it != (x).end(); it ++)

typedef pair PII;
const int N = 55555;
const int Q = 255555;
const int M = 401000;

char op[Q];
int qa[Q],qb[Q],ua[M],ub[M];
int from_small[N],n,m,nq,deg[N],on,first_on[N],edge_state[M],dot_state[N];
vector edge;
vector G[N];


int get_edge_id(PII z) {
        if (z.first>z.second) swap(z.first,z.second);
        return lower_bound(edge.begin(),edge.end(),z)-edge.begin();
}

void modify_dot(int u,int st) {
        dot_state[u] = st;
        int dt = st==1 ? 1 : -1;
        snuke(it,G[u]) {
                int v = it->first;
                int id = it->second;
                if (!edge_state[id]) continue;
                from_small[v] += dt;
        }
}

void modify_edge(int u,int v,int st) {
        int id = get_edge_id(PII(u,v));
        edge_state[id] = st;
        if (deg[u]>deg[v]) swap(u,v);
        if (dot_state[u]==1) {
                from_small[v] += st==1 ? 1 : -1;
        }
}

int query_dot(int u) {
        int ret = from_small[u];
        snuke(it,G[u]) {
                int v = it->first;
                int id = it->second;
                if (edge_state[id]==0) continue;
                ret += dot_state[v];
        }
        return ret;
}

void work() {
        sort(edge.begin(),edge.end());
        edge.erase(unique(edge.begin(),edge.end()),edge.end());
        int sz = (int)edge.size();
        for (int i = 0; i < sz; i ++) {
                deg[edge[i].first] ++;
                deg[edge[i].second] ++;
        }

        for (int i = 0; i < sz; i ++) {
                int u = edge[i].first;
                int v = edge[i].second;
                if (deg[u]>deg[v]) swap(u,v);
                G[u].push_back(PII(v,i));
        }

        for (int i = 0; i < m; i ++) {
                int id = get_edge_id(PII(ua[i],ub[i]));
                edge_state[id] = 1;
        }

        for (int i = 0; i < on; i ++) {
                modify_dot(first_on[i],1);
        }

        for (int i = 0; i  < nq; i ++) {
                int u = qa[i];
                int v = qb[i];
                if (op[i]=='O') {
                        modify_dot(u,1);
                } else if (op[i]=='F') {
                        modify_dot(u,0);
                } else if (op[i]=='A') {
                        modify_edge(u,v,1);
                } else if (op[i]=='D') {
                        modify_edge(u,v,0);
                } else {
                        printf("%d\n",query_dot(u));
                }
        }
}

int main() {
        scanf("%d%d%d",&n,&m,&nq);
        scanf("%d",&on);
        for (int i =0 ; i < on; i ++) {
                scanf("%d",&first_on[i]); first_on[i] --;
        }
        for (int  i = 0; i < m; i ++) {
                scanf("%d%d",&ua[i],&ub[i]); ua[i] --; ub[i] --;
                if (ua[i]>ub[i]) swap(ua[i],ub[i]);
                edge.push_back(PII(ua[i],ub[i]));
        }
        for (int i = 0; i < nq; i ++) {
                char s[3];
                scanf("%s",s);
                op[i] = s[0];
                if (op[i]=='A' || op[i]=='D') {
                        scanf("%d%d",&qa[i],&qb[i]); qa[i] --; qb[i] --;
                        if (qa[i]>qb[i]) swap(qa[i],qb[i]);
                        edge.push_back(PII(qa[i],qb[i]));
                } else {
                        scanf("%d",&qa[i]); qa[i] --;
                }
        }
        work();
        return 0;
}


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved