OIer复健记录

Day1 2020.7.18

[数据类型]

·包括读入,输出,保留,对齐等

·int,char,double,long double,float,long long,short

[最大公因数,最小公倍数]

写法是这样的来着?

gcd

Day2 2020.7.22 我太水了

·freopen

·dfs

·质数判断

·memset,memcpy,sort之类的STL

·埃及分数(思路错了,我用double写的,GG)

Day3 2020.8.2 我是最水的

·memset的各种赋值(之前写的博客终于有用了哦哦哦)

·lower_bound(a,a+n,x) //查找>=x的第一个位置

·vector<int> a : sort( a.begin() , a.end() ), a.size(), a.resize(), a.push_back(), a.pop_back(), a.clear(), a.empty()

      vector之间可直接赋值或作为函数返回值

Day4 2020.8.5 我还是很水

·STL里set&map的使用

·栈,队列,优先队列(STL里也有,但自己写的比较快吧):push的反义词是pop!

 关于priority_queue的重载运算符

struct cmp{
    bool operator()(const int a,const int b)const{
        return a>b;//a比b的优先级小的时候返回True
    }
}
重载运算符(结构体)

·快读:主要是用while进行getchar(),还有要用ch<<1+ch<<3+ch^48加速,ch^48相当于ch-=‘0’

inline int rd(){
    ans=0;
    ch=getchar();
    while(ch<'0'||ch>'9') ch=getchar();
    while(ch>='0'&&ch<='9'){
        ans=(ans<<1)+(ans<<3)+(ch^48);
        ch=getchar();
    }
    return ans;
}
快读板子

·线段树:先贴个自己的板子

#include <cstdio>
#define ll long long
#define maxn 1000010
#define mid ((l+r)>>1)
#define lson x<<1
#define rson x<<1|1
int n,m,opr,a,b,c;
int len[maxn];
ll sum[maxn],flag[maxn];
void push_up(int x){
    sum[x]=(sum[lson]+sum[rson]);
}
void build(int x,int l,int r){
    len[x]=r-l+1;
    if(l==r){
        scanf("%lld",&sum[x]);
        return;
    }
    build(lson,l,mid);
    build(rson,mid+1,r);
    push_up(x);
    return;
}
void push_down(int x){
    flag[lson]+=flag[x];
    flag[rson]+=flag[x];
    sum[lson]+=flag[x]*len[lson];
    sum[rson]+=flag[x]*len[rson];
    flag[x]=0;
}
void add(int x,int cl,int cr,int l,int r,int val){//cl,cr为需要修改的区间
    push_down(x);
    if(cl==l&&r==cr){
        flag[x]+=val;
        sum[x]+=(r-l+1)*val;
        return;
    }
    if(cr<=mid) add(lson,cl,cr,l,mid,val);
    else if(cl>mid) add(rson,cl,cr,mid+1,r,val);
    else add(lson,cl,mid,l,mid,val),add(rson,mid+1,cr,mid+1,r,val);
    push_up(x);
    return;
}
ll query(int x,int cl,int cr,int l,int r){
    push_down(x);
    if(cl==l&&r==cr){
        return sum[x];
    }
    ll ret=0;
    if(cr<=mid) ret+=query(lson,cl,cr,l,mid);
    else if(cl>mid) ret+=query(rson,cl,cr,mid+1,r);
    else ret+=query(lson,cl,mid,l,mid),ret+=query(rson,mid+1,cr,mid+1,r);
    return ret;
}
int main(){
    scanf("%d%d",&n,&m);
    build(1,1,n);
    for(int i=1;i<=m;i++){
        scanf("%d%d%d",&opr,&a,&b);
        if(opr==1){
            scanf("%d",&c);
            add(1,a,b,1,n,c);
            continue;
        }
        printf("%lld
",query(1,a,b,1,n));    
    }
    return 0;
}
线段树

 Day5 2020.8.6 小水孩做小水题

·洛谷P1890 gcd区间 线段树数组开小了,结果惨遭RE(已AC)

·CF229B 开始图论讨伐!先拿SPFA开刀好了,存图从vector改成了链式前向星 (艰难地AC了,这题数据设置的有点坑)

 诶,什么,你说SPFA已经死了?Σ(っ °Д °;)っ

卡SPFA的人都坏坏! 

void spfa(){
    dis[1]=0,in[1]=1,q.push(1);
    while(!q.empty()){
        tp=q.front(),q.pop(),in[tp]=0;
        tval=dis[tp];
        while(s[tp].count(tval)) 
            tval++;
        for(int i=head[tp];~i;i=e[i].nxt){
            nw=e[i].to;
            if(tval+e[i].w<dis[nw]){
                dis[nw]=tval+e[i].w;
                if(!in[nw]) 
                    q.push(nw),in[nw]=1;
            }
        }
    }
}
SPFA核心代码

·在terminal中复制(Ctrl+Insert)、粘贴(Shift+Insert)

Day6 2020.8.7 菜菜今天也要加油( •̀ ω •́ )y

 ·堆优化Dijkstra,讨伐开始!注:dijkstra不能跑负权环和最长路,最长路的贪心是错的

#include<stdio.h>
#include<queue>
#include<algorithm>
#include<iostream>
using namespace std;
int nex[400001];
int to[400001];
int val[400001];
int head[200001];
int f[200001];
int idx,x,y,z;
int inf=2147483647;
bool vis[200001];
struct Point
{
    int number,dis;
    inline bool operator < (const Point &a) const
    {
        return dis>a.dis;
    }
};
priority_queue <Point> q;
void addedge(int a,int b,int c)
{
    nex[++idx]=head[a];
    head[a]=idx;
    to[idx]=b;
    val[idx]=c;
}
int n,m,s;
int main()
{
    Point tmp;
    scanf("%d%d%d",&n,&m,&s);
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d%d",&x,&y,&z);
        addedge(x,y,z);
    }
    for(int i=1;i<=n;i++)
        f[i]=inf;
    tmp.number=s,tmp.dis=0;
    f[tmp.number]=0;  
    q.push(tmp);
    while(!q.empty())
    {
        int here=q.top().number;
        q.pop();
        if(vis[here])
            continue;
        vis[here]=1;
        for(int j=head[here];j;j=nex[j])
            if(f[to[j]]>val[j]+f[here]&&(!vis[to[j]]))
            {
                f[to[j]]=f[here]+val[j];
                tmp.number=to[j];
                tmp.dis=f[to[j]];
                q.push(tmp);
            }
    }
    for(int i=1;i<=n;i++)
        printf("%d ",f[i]);
}
Dijkstra

·拓扑排序 码是随便写的,凑一下工作量

#include <queue>
#include <cstdio>
#define N 10005
using namespace std;
queue<int> q;
bool vis[N];
int a,b,n,m,tmp,cnt,in[N];
int head[N],to[N],nxt[N];
inline void add(int u,int v){
    nxt[++cnt]=head[u];
    to[cnt]=v,head[u]=cnt;
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++){
        scanf("%d%d",&a,&b);
        add(a,b),in[b]++;
    }
    for(int i=1;i<=n;i++){
        if(!in[i])  q.push(i),vis[i]=1;
    }
    while(!q.empty()){
        tmp=q.front(),q.pop();
        printf("%d ",tmp);
        for(int i=head[tmp];i;i=nxt[i]){
            if(vis[to[i]]) continue;
            in[to[i]]--;
            if(!in[to[i]]) 
                q.push(to[i]),vis[to[i]];
        }
    }
    return 0;
}
拓扑序

·[无向图的欧拉回路]

  欧拉道路:如果一个无向图是连通的,且最多只有两个奇点,则一定存在欧拉道路。如果有两个奇点,则必须从一个奇点出发,以另一个奇点结束。

  欧拉回路:如果奇点不存在,则可以从任意点出发,最终一定会回到该点。

 [有向图的欧拉回路]

  最多只能有两个点的入度≠出度,且一个多1,另一个少1;忽略边的方向后,图必须联通

·Tarjan 缩强连通分量 没完全理解(可能之前也没完全搞懂,印象不是很深),明天接着来

Day7 2020.8.8 看看今天能学多少

 摸了,仍然没理解Tarjan,倒是颓了不少深圳I/O!qwq

Day8 2020.8.9 今天不能再划水了

·Tarjan讨伐!贴个讲解 https://zhuanlan.zhihu.com/p/101923309

 啊......递归里面开全局变量一定要小心——调码半小时有感

#include <cstdio>
#include <algorithm>
#define N 100005
using namespace std;
struct Answer{
    int u,v;
}ans[N];
bool is_bridge[N];
int n,m,nw,num,cnt=1,val[N];
int a,b,head[N],to[N],nxt[N];
int low[N],dfn[N],ans_tot,edge_tot;
void add(int a,int b){
    nxt[++cnt]=head[a];
    head[a]=cnt,to[cnt]=b;
}
void tarjan(int s,int edge){
    low[s]=dfn[s]=++num;
    for(int i=head[s];i;i=nxt[i]){
        int nw=to[i];
        if(!dfn[nw]){
            tarjan(nw,i);
            low[s]=min(low[s],low[nw]);
            if(low[nw]>dfn[s]){
                is_bridge[i]=is_bridge[i^1]=1;
            }
        }
        else if(i!=(edge^1))
            low[s]=min(low[s],dfn[nw]);
    }
}
bool cmp(Answer x,Answer y){
    if(x.u==y.u) return x.v<y.v;
    return x.u<y.u;
}
// bool operator <(const Answer x,const Answer y){
//     if(x.u==y.u) return x.v<y.v;
//     return x.u<y.u;
// }
int main(){
    scanf("%d%d",&n,&m);
    for(int i=0;i<m;i++){
        scanf("%d%d",&a,&b);
        add(a,b),add(b,a);
    }
    for(int i=1;i<=n;i++){
        if(!dfn[i]) tarjan(i,0);
    }
    edge_tot=m*2+1;
    for(int i=2;i<edge_tot;i+=2){
        if(is_bridge[i]){
            ans[++ans_tot].u=to[i^1];
            ans[ans_tot].v=to[i];
            if(ans[ans_tot].u>ans[ans_tot].v)
                swap(ans[ans_tot].u,ans[ans_tot].v);
        }
    }
    sort(ans+1,ans+ans_tot+1,cmp);
    for(int i=1;i<=ans_tot;i++){
        printf("%d %d
",ans[i].u,ans[i].v);
    }
    return 0;
}
Tarjan割边

我居然被sort卡了一上午(忘+1了),啊

·比较函数写法 https://blog.csdn.net/witnessai1/article/details/47395551

原文地址:https://www.cnblogs.com/al76/p/13374823.html