【滚动复习】滚动复习集中区3

来源:互联网 发布:出国移动wifi租赁 淘宝 编辑:程序博客网 时间:2024/06/09 16:51

关系运算图

无解的判断是松弛次数大于n而不是大于等于n,具体是为什么??(难道说还需要自己松弛一次自己??)

相等的边建其中一条就行了,不需要建双向边。不然肯定超时。

#include <cstdio>#include <string>#include <cstring>#include <cstdlib>long que[2000010];long qmod = 2000000;long dist[1010];long cnt[1010];bool used[1010];long n;struct node{    long ind;    long val;    node* nxt;};node* head[1010];void insert(long a,long b,long c){    node* nn = new node;    nn -> ind = b;    nn -> nxt = head[a];    nn -> val = c;    head[a] = nn;}long getint(){    long rs=0;bool sgn=1;char tmp;    do tmp = getchar();    while (!isdigit(tmp)&&tmp!='-');    if (tmp=='-'){tmp=getchar();sgn=0;}    do rs=(rs<<3)+(rs<<1)+tmp-'0';    while (isdigit(tmp=getchar()));    return sgn?rs:-rs;}void spfa(){    long l = 0;    long r = 0;//    memset(dist,~0x7f,sizeof dist);//    dist[0] = 0;//    que[++r] = 0;    for (long i=1;i<n+1;i++)    {        r ++;        que[r] = i;        dist[i] = 0;    }    while (l != r)    {        l ++;        if (l == qmod)            l = 0;        long u = que[l];        used[u] = false;        for (node* vv=head[u];vv;vv=vv->nxt)        {            long v = vv->ind;            if (dist[v]<dist[u]+vv->val)            {                dist[v] = dist[u]+vv->val;                cnt[v] ++;                if (cnt[v] > n)                {                    printf("NO");                    exit(0);                }                if (!used[v])                {                    used[v] = true;                    r ++;                    if (r == qmod)                        r = 0;                    que[r] = v;                }            }        }    }}int main(){    freopen("relation.in","r",stdin);    freopen("relation.out","w",stdout);    n = getint();    long m = getint();    for (long i=1;i<m+1;i++)    {        long a = getint();        long b = getint();        long c = getint();        if (c == -1)        {            insert(a,b,1);        }        if (c == 0)        {            insert(a,b,0);            //insert(b,a,0);        }        if (c == 1)        {            insert(b,a,1);        }    }//    for (long i=1;i<n+1;i++)//    {//        insert(0,i,0);//    }    spfa();    long ans = 0;    for (long i=1;i<n+1;i++)        if (ans < dist[i])            ans = dist[i];    printf("%ld",ans);        return 0;}

序列操作

一开始忘了讨论ll<=mid<rr的情况

#include <cstdio>#include <string> long tree[400010]; long getint(){    long rs=0;bool sgn=1;char tmp;    do tmp = getchar();    while (!isdigit(tmp)&&tmp!='-');    if (tmp=='-'){tmp=getchar();sgn=0;}    do rs=(rs<<3)+(rs<<1)+tmp-'0';    while (isdigit(tmp=getchar()));    return sgn?rs:-rs;} void change(long l,long r,long u,long ll,long rr){    long m = (l+r)>>1;    if (ll<=l && rr>=r)    {        tree[u] ++;    }    else if (rr < m+1)    {        change(l,m,u<<1,ll,rr);    }    else if (ll > m)    {        change(m+1,r,(u<<1)+1,ll,rr);    }    else    {        change(l,m,u<<1,ll,m);        change(m+1,r,(u<<1)+1,m+1,rr);    }} long find(long l,long r,long u,long x){    long m = (l+r)>>1;    if (l == r)    {        return tree[u] & 1;    }    if (x < m+1)    {        return (tree[u] + find(l,m,u<<1,x))&1;    }    else if (x > m)    {        return (tree[u] + find(m+1,r,(u<<1)+1,x))&1;    }} int main(){    long n = getint();    long p = getint();    for (long i=1;i<p+1;i++)    {        long k = getint();        if (k == 1)        {            long x = getint();            long y = getint();            change(1,n,1,x,y);        }        else        {            long x = getint();            long ans = find(1,n,1,x) & 1;            printf("%ld\n",ans);        }    }    return 0;}

小气的小B

#include <cstdio>#include <string> long st[50010][50];long st2[50010][50];long fruit[50010]; long getint(){    long rs=0;bool sgn=1;char tmp;    do tmp = getchar();    while (!isdigit(tmp)&&tmp!='-');    if (tmp=='-'){tmp=getchar();sgn=0;}    do rs=(rs<<3)+(rs<<1)+tmp-'0';    while (isdigit(tmp=getchar()));    return sgn?rs:-rs;} inline long lg2(long a){    long rs = 0;    while (a >>= 1) rs++;    return rs;} inline long lower(long a,long b){    if (fruit[a] < fruit[b])        return a;    return b;} inline long upper(long a,long b){    if (fruit[a] > fruit[b])        return a;    return b;} int main(){    long n = getint();    long p = getint();    for (long i=1;i<n+1;i++)    {        fruit[i] = getint();    }    for (long i=1;i<n+1;i++)    {        st[i][0] = i;        st2[i][0] = i;    }    long r = lg2(n);    for (long j=1;j<r+1;j++)    {        for (long i=1;i+(1<<j)-1<n+1;i++)        {            st[i][j] = lower(st[i][j-1],st[i+(1<<(j-1))][j-1]);            st2[i][j] = upper(st2[i][j-1],st2[i+(1<<(j-1))][j-1]);        }    }    for (long i=1;i<p+1;i++)    {        long a = getint();        long b = getint();        long len = lg2(b-a+1);        printf("%ld %ld\n",fruit[upper(st2[a][len],st2[b-(1<<len)+1][len])],fruit[lower(st[a][len],st[b-(1<<len)+1][len])]);    }    return 0;}

树的直径

#include <cstdio>#include <string> const long inf = 0x7f7f7f7f;long maxdist;long dest; struct node{    long v;    node* nxt;    long ind;};node* head[10010]; long getint(){    long rs=0;bool sgn=1;char tmp;    do tmp = getchar();    while (!isdigit(tmp)&&tmp!='-');    if (tmp=='-'){tmp=getchar();sgn=0;}    do rs=(rs<<3)+(rs<<1)+tmp-'0';    while (isdigit(tmp=getchar()));    return sgn?rs:-rs;}void insert(long a,long b,long v){    node* nn = new node;    nn -> ind = b;    nn -> nxt = head[a];    nn -> v = v;    head[a] = nn;} void dfs(long u,long uu,long d){    if (maxdist < d)    {        maxdist = d;        dest = u;    }    for (node* vv=head[u];vv;vv=vv->nxt)    {        long v = vv->ind;        if (v == uu) continue;        dfs(v,u,d+vv->v);    }} int main(){    long n = getint();    for (long i=1;i<n;i++)    {        long a = getint();        long b = getint();        long v = getint();        insert(a,b,v);        insert(b,a,v);    }    maxdist = -inf;    dfs(1,0,0);    maxdist = -inf;    dfs(dest,0,0);    printf("%ld",maxdist);    return 0;}

舞会

#include <cstdio>#include <string>#include <cstring> long cnt[210];long DFN[210];long LOW[210];bool Instack[210];long Stack[210];long tim = 0;long Bcnt = 0;long top = 0; struct node{    long ind;    node* nxt;};node* head[210];inline long getint(){    long rs=0;bool sgn=1;char tmp;    do tmp = getchar();    while (!isdigit(tmp)&&tmp-'-');    if (tmp == '-'){tmp=getchar();sgn=0;}    do rs=(rs<<3)+(rs<<1)+tmp-'0';    while (isdigit(tmp=getchar()));    return sgn?rs:-rs; }void insert(long a,long b){    node* nn = new node;    nn -> ind = b;    nn -> nxt = head[a];    head[a] = nn;} inline long min(long a,long b){    return a<b?a:b;}inline long max(long a,long b){    return a>b?a:b;} void tarjan(long u){    DFN[u] = LOW[u] = ++tim;    Instack[u] = true;    Stack[++top] = u;    for (node* vv=head[u];vv;vv=vv->nxt)    {        long v = vv->ind;        if (!DFN[v])        {            tarjan(v);            LOW[u] = min(LOW[u],LOW[v]);        }        else if (Instack[v] && DFN[v]<DFN[u])        {            DFN[u] = DFN[v];        }    }    if (DFN[u] == LOW[u])    {        Bcnt ++;        long v;        do        {            v = Stack[top--];            Instack[v] = false;            //cnt[Bcnt] ++;        }while (v != u);    }} int main(){    long n = getint();    for (long i=1;i<n+1;i++)    {        long v;        while (1)        {            v = getint();            if (!v) break;            insert(i,v);        }    }    for (long i=1;i<n+1;i++)        if (!DFN[i])            tarjan(i);     long ans = 0;    for (long i=1;i<Bcnt+1;i++)    {        ans = max(ans,cnt[i]);    }    //printf("%ld",n-ans);    printf("%ld",Bcnt);    return 0;}