我的hihocoder存代码

hihocoder的教程挺好理解,这里存代码。

1014 Trie树

#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
#define ll long long
#define eps 10^(-6)
#define Q_CIN ios::sync_with_stdio(false);
#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define CLR( a , x ) memset ( a , x , sizeof (a) );
#define RE freopen("1.in","r",stdin);
#define WE freopen("1.out","w",stdout);
#define MOD 10009
#define debug(x) cout<<#x<<":"<<(x)<<endl;
#define lson i<<1,l,m
#define rson i<<1|1,m+1,r

struct tree
{
    tree *next[27];
    int cnt;
    tree(){
        cnt=0;
        CLR(next,NULL);
    }
};
int n,m;
void add(tree *p,char *s1)
{
    int i=0;
    while(s1[i])
    {
        int k=s1[i]-'a';
        if(!p->next[k])
            p->next[k]=new tree();
        p=p->next[k];
        p->cnt++;
        i++;
    }
}
int query(tree *p,char *s1)
{
    int i=0;
    while(s1[i])
    {
        int k=s1[i]-'a';
        if(!p->next[k]) return 0;
        p=p->next[k];
        i++;
    }
    return p->cnt;
}

int main()
{
//    freopen("1.in","r",stdin);
    int n,m;
    char s1[30];
    while(~scanf("%d%*c",&n))
    {
        tree *p=new tree();
        for(int i=1;i<=n;i++)
        {
            scanf("%s",s1);
            add(p,s1);
        }
        scanf("%d%*c",&m);
        for(int i=1;i<=m;i++)
        {
            scanf("%s",s1);
            printf("%d\n",query(p,s1));
        }
    }
    return 0;
}

1015 KMP算法

#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
#define ll long long
#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define CLR( a , x ) memset ( a , x , sizeof (a) );
#define RE freopen("1.in","r",stdin);
#define WE freopen("1.out","w",stdout);

int Next[10005];
string s1,s2;
void getNext(string s1)
{
    int i=-1,j=0;
    int len=s1.length();
    Next[0]=-1;
    while(j<len)
    {
        if(i==-1||s1[i]==s1[j])
            Next[++j]=++i;
        else
            i=Next[i];
    }

}

int kmp(string s1,string s2)        //s2里找s2,可重叠
{
    int i=0,j=0;
    int len1=s1.length();
    int len2=s2.length();
    int cnt=0;
    for(int i=0;i<len1;i++)
    {
        while(j!=-1&&s1[i]!=s2[j])
            j=Next[j];
        if(j==-1||s1[i]==s2[j])
            j++;
        if(j==len2)
            cnt++;
    }
    return cnt;
}
int main()
{
    RE
    int n;
    cin>>n;
    for(int i=0;i<n;i++)
    {
        cin>>s1>>s2;
        getNext(s1);
        cout<<kmp(s2,s1)<<endl;
    }
}

1032 最长回文子串

#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
#define ll long long
#define eps 10^(-6)
#define Q_CIN ios::sync_with_stdio(false);
#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define CLR( a , x ) memset ( a , x , sizeof (a) );
#define RE freopen("1.in","r",stdin);
#define WE freopen("1.out","w",stdout);
#define MOD 10009
#define bug(x) cout<<#x<<":"<<(x)<<endl;

char s1[1000020],s2[2000100];
int len[1000000*2+8];

int init()
{
    int len=strlen(s1),cnt=0;
    REP(i,len){
        s2[cnt++] = '#';
        s2[cnt++] = s1[i];
    }
    s2[cnt++]='#';
    s2[cnt]='\0';
    return strlen(s2);
}

int Manacher()
{
    int n=init();
    int pos=0,mx=0,ans=1;
    FOR(i,0,n-1){
        if(mx>i){
            len[i]=min(len[pos*2-i],mx-i);
        }else{
            len[i]=1;
        }
        while(i-len[i]>=0&&s2[i+len[i]]==s2[i-len[i]])  {
                len[i]++;
        }
        if(len[i]+i>mx){
            mx=len[i]+i;
            pos=i;
        }
        ans=max(ans,len[i]);
    }
    return ans-1;
}

int main()
{
//     RE
    int t;
    scanf("%d%*c",&t);
    while(t--){
        scanf("%s",s1);
        printf("%d\n",Manacher());
    }
    return 0;
}

1050 树中的最长路

#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <map>
#include <queue>
#include <set>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
#define ll long long
#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define CLR( a , x ) memset ( a , x , sizeof (a) );
#define MOD 10009
#define bug(x) cout<<#x<<":"<<(x)<<endl;

vector<vector<int> > v;
int src,len;
// 任意一个点dfs求距离它最远的点,再从该点dfs求距离该点最远的点,则这次距离就是了
void dfs(int u,int depth,int father){       //father:父结点
    if( depth > len){
        len = depth;
        src = u;
    }
    for (int i = 0; i < v[u].size(); ++i){
        if(father != v[u][i])       //不能走回头路
            dfs(v[u][i],depth+1,u);
    }
}

int main(){

    int n,a,b;
    cin>>n;
    v.resize(n+1);      //!!!!!!!!!!!!!
    for (int i = 0; i < n-1; ++i){
        cin>>a>>b;
        v[a].push_back(b);
        v[b].push_back(a);
    }
    len = 0;
    dfs(1,0,0);
    len = 0;
    dfs(src,0,0);
    cout<<len<<endl;
    return 0;
}

1093 最短路径·三:SPFA算法

#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
#define ll long long
#define eps 10^(-6)
#define Q_CIN ios::sync_with_stdio(false);
#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define CLR( a , x ) memset ( a , x , sizeof (a) );
#define RE freopen("1.in","r",stdin);
#define WE freopen("1.out","w",stdout);
#define MOD 10009
#define debug(x) cout<<#x<<":"<<(x)<<endl;
const int maxn=1e5+5;
const int maxm=1e6+5;
const int inf=1e3*maxm;
int inq[maxn],head[maxn],dis[maxn];
struct Edge
{
    int v,w,next;
}edge[maxm*2];
int cnt;
void add_edge(int u,int v,int w)
{
    edge[cnt].v=v;edge[cnt].w=w;edge[cnt].next=head[u];head[u]=cnt++;
}
void init(int n)
{
    cnt=0;
    CLR(head,-1);
    CLR(inq,0);
    FOR(i,1,n)
        dis[i]=inf;
}
int spfa(int s,int t)
{
    queue<int>q;
    dis[s]=0;
    inq[s]=1;
    q.push(s);
    while(!q.empty())
    {
        int u=q.front();q.pop();
        inq[u]=0;
        for(int i=head[u];i!=-1;i=edge[i].next)
        {
            int v=edge[i].v;
            int w=edge[i].w;
            if(dis[v]>dis[u]+w)
            {
                dis[v]=dis[u]+w;
                if(!inq[v])
                {
                    inq[v]=1;
                    q.push(v);
                }
            }
        }
    }
    return dis[t];
}
int main()
{
//    RE
    int n,m,s,t,a,b,c;
    while(cin>>n>>m>>s>>t)
    {
        init(n);
        REP(i,m)
        {
            cin>>a>>b>>c;
            add_edge(a,b,c);
            add_edge(b,a,c);
        }
        cout<<spfa(s,t)<<endl;
    }
    return 0;
}

1121 二分图一•二分图判定

给定的图可能不联通,所以一次搜索不行,如例子:
4 2
1 2
3 4
应为Correct

BFS
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
#define ll long long
#define INF 0x7FFFFFFF
#define INT_MIN -(1<<31)
#define eps 10^(-6)
#define Q_CIN ios::sync_with_stdio(false);
#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define CLR( a , x ) memset ( a , x , sizeof (a) );
#define RE freopen("1.in","r",stdin);
#define WE freopen("1.out","w",stdout);
#define MOD 10009
#define debug(x) cout<<#x<<":"<<(x)<<endl;
const int maxn=10050;
vector<int>v[maxn];
int vis[maxn];
int n;
int match(int s)
{
    queue<int>q;
    q.push(s);
    vis[s]=1;
    int flag=0;
    while(!q.empty())
    {
        int pre=q.front();
        q.pop();
        for(int i=0;i<v[pre].size();i++)
        {
            int x=v[pre][i];
            if(vis[x]==-1)
            {
                vis[x]=!vis[pre];
                q.push(x);
            }else if(vis[x]==vis[pre])
                return 0;
        }
    }
    return 1;
}
int main()
{
//    RE
    int t,m,a,b;
    cin>>t;
    while(t--)
    {
        cin>>n>>m;
        FOR(i,1,n)
            v[i].clear();
        CLR(vis,-1);

        REP(i,m)
        {
            cin>>a>>b;
            v[a].push_back(b);
            v[b].push_back(a);
        }
        int ok=1;
        FOR(i,1,n)
        {
            if(vis[i]==-1&&!match(i))
            {
                ok=0;
                cout<<"Wrong"<<endl;
                break;
            }
        }
        if(ok)
            cout<<"Correct"<<endl;
    }
    return 0;
}
DFS
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
#define ll long long
#define INF 0x7FFFFFFF
#define INT_MIN -(1<<31)
#define eps 10^(-6)
#define Q_CIN ios::sync_with_stdio(false);
#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define CLR( a , x ) memset ( a , x , sizeof (a) );
#define RE freopen("1.in","r",stdin);
#define WE freopen("1.out","w",stdout);
#define MOD 10009
#define debug(x) cout<<#x<<":"<<(x)<<endl;
const int maxn=10050;
vector<int>v[maxn];
int vis[maxn];
int n;
int dfs(int s)
{
    for(int i=0;i<v[s].size();i++)
    {
        int x=v[s][i];
        if(vis[x]==-1)
        {
            vis[x]=!vis[s];
            if(!dfs(x)) return 0;
        }else if(vis[x]==vis[s])
            return 0;
    }
    return 1;
}
int main()
{
    RE
    int t,m,a,b;
    cin>>t;
    while(t--)
    {
        cin>>n>>m;
        FOR(i,1,n)
            v[i].clear();
        CLR(vis,-1);

        REP(i,m)
        {
            cin>>a>>b;
            v[a].push_back(b);
            v[b].push_back(a);
        }
        int ok=1;
        FOR(i,1,n)
        {
            if(vis[i]==-1)
            {
                vis[i]=1;       //不能放进dfs里
                if(!dfs(i))    
                {
                    ok=0;
                    cout<<"Wrong"<<endl;
                    break;
                }
            }
        }
        if(ok)
            cout<<"Correct"<<endl;
    }
    return 0;
}

1122 二分图二 分图最大匹配之匈牙利算法

注意可能有多个联通块

#include <cstdio>
#include <cstring>
#include <queue>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
#define ll long long
#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define CLR( a , x ) memset ( a , x , sizeof (a) );
#define RE freopen("1.in","r",stdin);
#define WE freopen("1.out","w",stdout);
const int maxn=1005;
const int maxm=5005;

int mat[maxn][maxn];
int arr[maxn][maxn];
int vis[maxn];
int match[maxn];
int team[maxn];

int n,m;
int cnt;

int can(int u)
{
    for(int v=1;v<=n;v++)
    {
        if(mat[u][v]&&!vis[v])
        {
            vis[v]=1;
            if(match[v]==-1||can(match[v]))
            {
                match[v]=u;match[v]=u;
                return 1;
            }
        }
    }
    return 0;
}
void bfs(int u)
{
    queue<int>q;
    q.push(u);
    team[u]=0;
    while(!q.empty())
    {
        int x=q.front();q.pop();
        for(int i=1;i<=n;i++)
        {
            if(arr[x][i]&&team[i]==-1)
            {
                team[i]=!team[x];
                q.push(i);
            }
        }
    }
}
int main()
{
//    RE
    int a,b;
    while(cin>>n>>m)
    {
        cnt=0;
        CLR(mat,0);
        CLR(arr,0);
        CLR(team,-1);
        REP(i,m)
        {
            cin>>a>>b;
            if(a!=b)
                arr[a][b]=arr[b][a]=mat[a][b]=mat[b][a]=1;
        }
        for(int i=1;i<=n;i++)
        {
            if(team[i]==-1)
            {
                bfs(i);
            }
        }
        CLR(match,-1);
        FOR(i,1,n)
        {
            CLR(vis,0);
            if(!team[i]&&can(i))
                cnt++;
        }
        cout<<cnt<<endl;
    }
    return 0;
}

二分图三 二分图最小点覆盖和最大独立集

#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
#define ll long long
#define eps 10^(-6)
#define Q_CIN ios::sync_with_stdio(false);
#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define CLR( a , x ) memset ( a , x , sizeof (a) );
#define RE freopen("1.in","r",stdin);
#define WE freopen("1.out","w",stdout);
#define MOD 10009
#define debug(x) cout<<#x<<":"<<(x)<<endl;
#define lson i<<1,l,m
#define rson i<<1|1,m+1,r

int n,m;
int link[1005],vis[1005];
int mat[1005][1005];
int team[1005];
int can(int u)
{
    for(int v=1;v<=n;v++)
    {
        if(mat[u][v]&&!vis[v])
        {
            vis[v]=1;
            if(link[v]==-1||can(link[v]))
            {
                link[v]=u;
                return 1;
            }
        }
    }
    return 0;
}
void bfs(int x)
{
    queue<int>q;
    q.push(x);
    team[x]=0;
    while(!q.empty())
    {
        int t=q.front();q.pop();
        for(int v=1;v<=n;v++)
            if(mat[t][v]&&team[v]==-1)
            {
                team[v]=!team[t];
                q.push(v);
            }
    }
}
int main()
{
//    freopen("1.in","r",stdin);
    int a,b;
    while(~scanf("%d%d",&n,&m))
    {
        memset(mat,0,sizeof(mat));
        memset(link,-1,sizeof(link));
        memset(team,-1,sizeof(team));
        int cnt=0;
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&a,&b);
            mat[a][b]=mat[b][a]=1;
        }
        for(int i=1;i<=n;i++)
            if(team[i]==-1)
                bfs(i);
        for(int i=1;i<=n;i++)
        {
            memset(vis,0,sizeof(vis));
            if(!team[i]&&can(i))  cnt++;
        }
        printf("%d\n%d\n",cnt,n-cnt);
    }
    return 0;
}

RMQ-ST算法

cin超时

#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
#define ll long long
#define eps 10^(-6)
#define Q_CIN ios::sync_with_stdio(false);
#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define CLR( a , x ) memset ( a , x , sizeof (a) );
#define RE freopen("1.in","r",stdin);
#define WE freopen("1.out","w",stdout);
#define MOD 10009
#define debug(x) cout<<#x<<":"<<(x)<<endl;
#define lson i<<1,l,m
#define rson i<<1|1,m+1,r
int arr[1000005],dp[1000005][20];
int n,m;
void init()
{
    for(int i=1;i<=n;i++)
        dp[i][0]=arr[i];
    for(int j=1;(1<<j)<=n;j++)
    {
        for(int i=1;i+(1<<j)-1<=n;i++)
        {
            dp[i][j]=min(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
        }
    }
}
int query(int l,int r)
{
    int k=(int)log2(r-l+1.0);
    return min(dp[l][k],dp[r-(1<<k)+1][k]);
}
int main()
{
//    freopen("1.in","r",stdin);
    int l,r;
    scanf("%d",&n);
    {
        for(int i=1;i<=n;i++)
            scanf("%d",&arr[i]);
        scanf("%d",&m);
        init();
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&l,&r);
            printf("%d\n",query(l,r));
        }
    }
    return 0;
}

1077 RMQ问题再临-线段树

单点更新,区间查询

#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <map>
#include <queue>
#include <iostream>
#include <algorithm>
using namespace std;
#define ll long long
#define clr( a , x ) memset ( a , x , sizeof (a) );
#define RE freopen("1.in","r",stdin);
#define WE freopen("1.out","w",stdout);
#define MOD 10009
#define bug(x) cout<<#x<<":"<<(x)<<endl;
#define lson rt<<1,l,m
#define rson rt<<1|1,m+1,r
const int maxn = 1e6 + 5;
const int maxm = 1e6 + 5;
const int inf = 0x3f3f3f3f;

int val[maxn << 2];
void build(int rt, int l, int r) {
    if (l == r) {
        scanf("%d",&val[rt]);
    } else {
        int m = (l + r) >> 1;
        build(lson);
        build(rson);
        val[rt] = min(val[rt << 1], val[rt << 1 | 1]);
    }
}
void update(int rt, int l, int r, int pos, int num) {
    if (l == r && r == pos) {
        val[rt] = num;
    } else {
        int m = (l + r) >> 1;
        if (pos <= m)
            update(lson, pos, num);
        else
            update(rson, pos, num);
        val[rt] = min(val[rt << 1], val[rt << 1 | 1]);
    }
}

int query(int rt, int l, int r, int q1, int q2) {
    if (q1 <= l && r <= q2) {
        return val[rt];
    }
    int m = (l + r) >> 1, t1 = inf, t2 = inf;
    if (q1 <= m)
        t1 = query(lson, q1, q2);
    if (q2 > m)
        t2 = query(rson, q1, q2);
    return min(t1, t2);
}

int main() {
    int a, b, c, m, n;
    scanf("%d",&n);
    build(1, 1, n);
    scanf("%d",&m);
    while (m--) {
        scanf("%d%d%d",&a,&b,&c);
        if (a) {
            update(1, 1, n, b, c);
        } else {
            printf("%d\n", query(1, 1, n, b, c));
        }
    }
    return 0;
}

1078 线段树的区间修改线段树

#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
#define ll long long
#define eps 10^(-6)
#define Q_CIN ios::sync_with_stdio(false);
#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define CLR( a , x ) memset ( a , x , sizeof (a) );
#define RE freopen("1.in","r",stdin);
#define WE freopen("1.out","w",stdout);
#define MOD 10009
#define debug(x) cout<<#x<<":"<<(x)<<endl;
#define lson i<<1,l,m
#define rson i<<1|1,m+1,r
int sum[1000005<<2],add[1000005<<2];
int n,m;
void build(int i,int l,int r)
{
    add[i]=0;
    if(l==r)
    {
        scanf("%d",&sum[i]);
        return;
    }
    int m=(l+r)/2;
    build(lson);
    build(rson);
    sum[i]=sum[i<<1]+sum[i<<1|1];
}

void pushdown(int i,int m)
{
    add[i<<1]=add[i<<1|1]=add[i];
    sum[i<<1]=add[i]*(m-m/2);
    sum[i<<1|1]=add[i]*(m/2);
    add[i]=0;
}
void update(int i,int l,int r,int q1,int q2,int num)
{
    if(q1<=l&&r<=q2)
    {
        add[i]=num;
        sum[i]=(r-l+1)*num;
        return;
    }
    int m=(l+r)/2;
    if(add[i])
        pushdown(i,r-l+1);
    if(q1<=m)
        update(lson,q1,q2,num);
    if(q2>m)
        update(rson,q1,q2,num);
    sum[i]=sum[i<<1]+sum[i<<1|1];
}
int query(int i,int l,int r,int q1,int q2)
{
    if(q1<=l&&r<=q2) return sum[i];
    if(add[i])
        pushdown(i,r-l+1);
    int m=(l+r)/2;
    int t1=0,t2=0;
    if(q1<=m)
        t1=query(lson,q1,q2);
    if(q2>m)
        t2=query(rson,q1,q2);
    return t1+t2;
}
int main()
{
//    freopen("1.in","r",stdin);
    int l,r,c,num;
    scanf("%d",&n);
    {
        build(1,1,n);
        scanf("%d",&m);
        for(int i=1;i<=m;i++)
        {
            scanf("%d",&c);
            if(c==0)
            {
                scanf("%d%d",&l,&r);
                printf("%d\n",query(1,1,n,l,r));
            }else{
                scanf("%d%d%d",&l,&r,&num);
                update(1,1,n,l,r,num);
            }
        }
    }
    return 0;
}

1080 更为复杂的买卖房屋姿势

#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
#define ll long long
#define eps 10^(-6)
#define Q_CIN ios::sync_with_stdio(false);
#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define CLR( a , x ) memset ( a , x , sizeof (a) );
#define RE freopen("1.in","r",stdin);
#define WE freopen("1.out","w",stdout);
#define MOD 10009
#define debug(x) cout<<#x<<":"<<(x)<<endl;
#define lson i<<1,l,m
#define rson i<<1|1,m+1,r
int sum[100010<<2],add[100010<<2],eva[100010<<2];

int n,m;
void build(int i,int l,int r)
{
    add[i]=0,eva[i]=0;
    if(l==r)
    {
        scanf("%d",&sum[i]);
        return;
    }
    int m=(l+r)/2;
    build(lson);
    build(rson);
    sum[i]=sum[i<<1]+sum[i<<1|1];
}
void pushdown_eva(int i,int m)
{
    eva[i<<1]=eva[i<<1|1]=eva[i];
    sum[i<<1]=eva[i]*(m-m/2);
    sum[i<<1|1]=eva[i]*(m/2);
    eva[i]=0;
    add[i<<1]=add[i<<1|1]=0; //赋值标记使得子区间的加值标记无效
}
void pushdown_add(int i,int m)
{
    add[i<<1]+=add[i];
    add[i<<1|1]+=add[i];
    sum[i<<1]+=add[i]*(m-m/2);
    sum[i<<1|1]+=add[i]*(m/2);
    add[i]=0;
}
void update(int i,int l,int r,int q1,int q2,int num,int c)
{
    if(q1<=l&&r<=q2)
    {
        if(c){
            sum[i]=(r-l+1)*num;
            eva[i]=num;
            add[i]=0;       //add标记被覆盖
        }
        else{
            sum[i]+=(r-l+1)*num;
            add[i]+=num;
        }
        return;
    }
    int m=(l+r)/2;
    if(eva[i])
        pushdown_eva(i,r-l+1);
    if(add[i])
        pushdown_add(i,r-l+1);
    if(q1<=m)
        update(lson,q1,q2,num,c);
    if(q2>m)
        update(rson,q1,q2,num,c);
    sum[i]=sum[i<<1]+sum[i<<1|1];
}
int query(int i,int l,int r,int q1,int q2)
{
    if(q1<=l&&r<=q2) return sum[i];
    if(eva[i])
        pushdown_eva(i,r-l+1);
    if(add[i])
        pushdown_add(i,r-l+1);
    int m=(l+r)/2;
    int t1=0,t2=0;
    if(q1<=m)
        t1=query(lson,q1,q2);
    if(q2>m)
        t2=query(rson,q1,q2);
    return t1+t2;
}
int main()
{
//    freopen("1.in","r",stdin);
    int l,r,c,num;
    scanf("%d%d",&n,&m);
    {
        n++;
        build(1,1,n);
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%d%d",&c,&l,&r,&num);
            l++;r++;
            update(1,1,n,l,r,num,c);
            printf("%d\n",query(1,1,n,1,n));
        }
    }
    return 0;
}

1044 状态压缩 一

#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
#define ll long long
#define eps 10^(-6)
#define Q_CIN ios::sync_with_stdio(false);
#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define CLR( a , x ) memset ( a , x , sizeof (a) );
#define RE freopen("1.in","r",stdin);
#define WE freopen("1.out","w",stdout);
#define MOD 10009
#define debug(x) cout<<#x<<":"<<(x)<<endl;
#define lson i<<1,l,m
#define rson i<<1|1,m+1,r
int dp[1005][1030];
int sum(int n)
{
    int ans=0;
    while(n)
    {
        ans+=n&1;
        n>>=1;
    }
    return ans;
}
int main()
{
//    freopen("1.in","r",stdin);
    int n,m,q;
    int a[1005];
    while(~scanf("%d%d%d",&n,&m,&q))
    {
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
//        memset(dp,0,sizeof(dp));
        for(int i=1;i<=n;i++)
            for(int j=0;j<(1<<m)-1;j++)
            {
                if(sum(j)<q)
                    dp[i][j]=max(dp[i-1][(j/2)+(1<<(m-2))],dp[i-1][j/2]);
                else if(sum(j)>q)
                    dp[i][j]=0;
                else
                    dp[i][j]=dp[i-1][j/2];
                if((j>>(m-2))&1) dp[i][j]+=a[i];
            }
            int ans=0;
        for(int j=0;j<(1<<m)-1;j++)
            ans=max(dp[n][j],ans);
        printf("%d\n",ans);
    }
    return 0;
}

1089 最短路径 二:Floyd算法

#include <cstdio>
#include <string.h>
#include <vector>
#include <algorithm>
#include <iostream>
#define rep( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define clr( a , x ) memset ( a , x , sizeof (a) );
using namespace std;
const int maxn = 105;
const int inf = 0x3f3f3f3f;

int n,m;
int dp[maxn][maxn];

void floyd(){
    rep(k,1,n){
        rep(i,1,n){
            rep(j,1,n){
                dp[i][j] = min(dp[i][j],dp[i][k]+dp[k][j]);
            }
        }
    }
}

int main(){
    int a,b,c;
    while(cin>>n>>m){
        clr(dp,inf);
        rep(i,1,n)
            dp[i][i]=0;
        rep(i,1,m){
            cin>>a>>b>>c;
            dp[a][b] = dp[b][a] = min(dp[a][b],c);
        }
        floyd();
        rep(i,1,n){
            rep(j,1,n-1){
                cout<<dp[i][j]<<" ";
            }
            cout<<dp[i][n]<<endl;
        }
    }
    return 0;
}

1097 最小生成树一 Prim算法

#include <iostream>
#include <algorithm>
#include <math.h>
#include <string.h>
#include <cmath>

using namespace std;
const int maxn = 1e3+50;
const int maxM = 25300*502;
int dis[maxn];
int vis[maxn];
int n;
int mp[maxn][maxn];

int prim(int src){

    for (int i = 1; i <= n; ++i){
        dis[i] = mp[src][i];
    }
    memset(vis,0,sizeof(vis));
    dis[src] = 0;
    vis[src] = 1;
    int ret = 0;

    for (int i = 1; i < n; ++i)
    {
        int minDis = 9999999,minIdx;
        for (int j = 1; j <= n; ++j)
        {
            if(!vis[j] && dis[j] < minDis){
                minDis = dis[j];
                minIdx = j;
            }
        }
        vis[minIdx] = 1;
        ret += minDis;

        for (int j = 1; j <= n; ++j)
        {
            // if(!vis[j] && dis[minIdx] + mp[minIdx][j] < dis[j]){
            //     dis[j] = dis[minIdx] + mp[minIdx][j];
            // }
            if(!vis[j] &&  mp[minIdx][j] < dis[j]){
                dis[j] =  mp[minIdx][j];
            }
        }

    }
    return ret;
}

int main() {

    while (cin >> n ) {
        for (int i = 1; i <= n; ++i) {
            for (int j = 1; j <= n; ++j) {
                cin >> mp[i][j];
            }
        }

        memset(dis, 0, sizeof(dis));

        int ret = prim(1);
       cout << ret << endl;
    }
    return 0;
}

1142 三分·三分求极值

#include <cstdio>
#include <cmath>
#include <iostream>
#include <algorithm>
using namespace std;
double a,b,c,x,y;

double val(double X){
    return sqrt((X-x)*(X-x)+(a*X*X+b*X+c-y)*(a*X*X+b*X+c-y));
}

double solve(double l,double r){
    double eps = 1e-5;
    while(l+eps<r){
        double lmid = l + (r-l)/3,rmid = r - (r-l)/3;
        if(val(lmid) < val(rmid)){
            r = rmid;
        }else{
            l = lmid;
        }
    }
    return val(l);
}
int main(){
    cin>>a>>b>>c>>x>>y;
    printf("%.3f\n", solve(-200.0,200.0));
    return 0;
}

1183 连通性一·割边与割点

Tarjan算法简化版,注意是无向边 和 边上点的大小关系

#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
#define ll long long
#define clr( a , x ) memset ( a , x , sizeof (a) );
#define RE freopen("1.in","r",stdin);
#define WE freopen("1.out","w",stdout);
#define SpeedUp std::cout.sync_with_stdio(false);
#define debug(x) cout << "Line " << __LINE__ << ": " << #x << " = " << x << endl;
const int maxn = 20005;
const int maxm = 200052;    //~无向边
const int inf = 0x3f3f3f3f;
int head[maxn];
int dfn[maxn], low[maxn];
int cnt;
bool vis[maxn];
int next[maxn];
int father[maxn];
int eCnt;
struct Edge
{
    int v, next;
} edge[maxm];
void add(int u, int v) {
    edge[eCnt].v = v, edge[eCnt].next = head[u], head[u] = eCnt++;
    edge[eCnt].v = u, edge[eCnt].next = head[v], head[v] = eCnt++;
}
struct B
{
    int u,v;
    bool operator < (const struct B bb) const{
        if(u==bb.u)
            return v<bb.v;
        return u<bb.u;
    }
}bridge[maxm]; //存答案的边
int bCnt;
bool node[maxn];
void dfs(int u) {
    dfn[u] = low[u] = cnt++;
    vis[u] = true;
    int child = 0;
    for (int i = head[u]; i != -1; i = edge[i].next) {
        int v = edge[i].v;
        if (!vis[v]) {
            child++;
            father[v] = u;
            dfs(v);
            low[u] = min(low[u], low[v]);
            if (father[u] == -1 && child >= 2) {
                node[u] = true;
            }
            if (father[u] != -1 && low[v] >= dfn[u]) {
                node[u] = true;
            }
            if (low[v] > dfn[u]) {
                bridge[bCnt].u = min(u,v);
                bridge[bCnt++].v = max(u,v);
            }
        }else if (v != father[u]) {
            low[u] = min(low[u], dfn[v]);
        }
    }
}
int main() {
    // RE
    int n, m;
    int a, b;
    while (cin >> n >> m) {
        eCnt = 0;
        clr(head, -1);
        clr(vis, false);
        clr(father,-1);
        clr(node,false);
        clr(dfn,0);
        clr(low,0);

        cnt = 0;
        bCnt = 0;

        for (int i = 0; i < m; ++i) {
            cin >> a >> b;
            add(a, b);
        }

        dfs(1);
        int first = true;
        int no = 1;
        for (int i = 1; i <= n; ++i){
            if(node[i]){
                if(first){
                    first = false;
                    cout<<i;
                }
                else{
                    cout<<" "<<i;
                }
                no = 0;
            }
        }
        if(no){
            cout<<"Null";
        }
        cout<<endl;
        sort(bridge,bridge+bCnt);
        for (int i = 0; i < bCnt; ++i){
            cout<<bridge[i].u<<" "<<bridge[i].v<<endl;
        }
        // for (int i = 1; i <= n; ++i){
        //     cout<<"dfn="<<dfn[i]<<" low="<<low[i]<<endl;
        // }
    }
    return 0;
}

1066 无间道之并查集

https://hihocoder.com/problemset/solution/1271732

#include <iostream>
#include <algorithm>
#include <math.h>
#include <string.h>
#include <cmath>
#include <map>

using namespace std;
const int maxn = 100005;
const int maxM = 25300*502;

int root[maxn*2];
int n;
int findRoot(int cur){
    if(cur == root[cur]){
        return cur;
    }
    return root[cur] = findRoot(root[cur] );
}

int merge(int x,int y){
    int rootX = findRoot(x);
    int rootY = findRoot(y);
    if(rootX != rootY){
        root[rootX] = rootY;
    }
}

int main() {
    int op;
    string str1,str2;
    map<string,int>mp;
    while (cin >> n ) {
        for (int i = 0; i <= n; i++) {
            root[i] = i;
        }
        mp.clear();

        int cnt = 0;
        for (int i = 0; i < n; i++) {
            cin >> op >> str1 >> str2;

            int idx1 ,idx2 ;
            idx1 = mp[str1];idx2 = mp[str2];

            if( mp[str1] == 0){
                idx1 = mp[str1] = ++cnt;
            }
            if( mp[str2] == 0){
                idx2 = mp[str2] = ++cnt;
            }   
            if(op==1){
                // cout<< idx1 << " " << idx2 << " === "<< endl;
                if( findRoot(idx1) == findRoot(idx2) ){
                    cout<<"yes"<<endl;
                }else{
                    cout<<"no"<<endl;
                }
            }else{

                merge(idx1,idx2);
                // for (int i = 0; i < cnt; i++) {
                    // cout<<word[i]<< " " << i << " "<<findRoot(i) << endl;
                // }

            }
        }
    }
    return 0;
}

1038 01背包

https://hihocoder.com/problemset/solution/1270589

#include <iostream>
#include <algorithm>
#include <math.h>
#include <string.h>
#include <cmath>

using namespace std;
const int maxN = 555;
const int maxM = 25300*502;

int main() {
    int n, m;
    int cost[maxN], val[maxN];
    int dp[maxM];

    while (cin >> n >> m) {
        for (int i = 0; i < n; ++i) {
            cin >> cost[i] >> val[i];
        }
        memset(dp, 0, sizeof(dp));

        int ans = 0;
        for (int i = 0; i < n; ++i) {
            for (int j = m; j >= cost[i]; --j) {
                dp[j] = max(dp[j], dp[j - cost[i]] + val[i]);
            }
        }
       cout << dp[m] << endl;
    }
    return 0;
}

1081 最短路径·一

https://hihocoder.com/problemset/solution/1271836 注意路是双向的,跟prim就差几行代码

#include <iostream>
#include <algorithm>
#include <math.h>
#include <string.h>
#include <cmath>

using namespace std;
const int maxn = 1e3+50;
const int maxM = 25300*502;
const int inf = 0x3f3f3f3f;
int dis[maxn];
int vis[maxn];
int n;
int mp[maxn][maxn];

int dijkstra(int src,int dst){

    for (int i = 1; i <= n; ++i){
        dis[i] = mp[src][i];
    }
    memset(vis,0,sizeof(vis));
    dis[src] = 0; vis[src] = 1;

    for (int i = 1; i < n; ++i)
    {
        int minDis = inf,minIdx = 0;
        for (int v = 1; v <= n; ++v)
        {
            if(!vis[v] && dis[v] < minDis){
                minDis = dis[v];
                minIdx = v;
            }
        }
        vis[minIdx] = 1;

        for (int v = 1; v <= n; ++v)
        {
            if(!vis[v] && dis[minIdx] + mp[minIdx][v] < dis[v]){
                dis[v] = dis[minIdx] + mp[minIdx][v];
            }
        }

    }
    return dis[dst];
}

int main() {
    int s,t,a,b,val,m;
    while (cin >> n >> m >> s >> t) {

        memset(mp, inf, sizeof(mp));
        for (int i = 0; i < m; ++i) {
            cin >> a >> b >> val;
            mp[b][a] = mp[a][b] = min(mp[a][b],val);
        }
        int ret = dijkstra(s,t);
        cout << ret << endl;
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值