树状数组-并查集

1.树状数组

给你一个序列a[1]~a[N],你需要找出每一个数a[i],在区间[1, i - 1]有多少个数小于等于a[i]。

int lowbit(int x)
{
    return x&(-x);
}
void update(int x,int y)
{
    while(x<=n)
    {
        c[x]+=y;
        x+=lowbit(x);
    }
    //return;//重点
}
int sum(int x)
{
    int ans=0;
    while(x>0)
    {
        ans+=c[x];
        x-=lowbit(x);
    }
    return ans;
}

给你一个初始全为0的序列a[1]~a[N],有q次操作,每次操作有两种类型,第一种操作时区间翻转操作,将区间[l, r]进行翻转,也就是原来为0的数现在变为1,原来为1的数现在变为0.第二组是查询操作,查询位置loc的值是0还是1.

int lowbit(int x)
{
    return x&(-x);
}
void update(int l,int r)
{
    while(l>0)
    {
        w[l]+=1;
        l-=lowbit(l);
    }
    while(r>0)
    {
        w[r]+=1;
        r-=lowbit(r);
    }
}
int sum(int x)
{
    int sum=0;
    while(x<=N)
    {
        sum+=w[x];
        x+=lowbit(x);
    }
    return sum;
}

2.并查集

把这些柱子当成N个节点,编号为1~N,然后给你若干条边,每条边连接两个点,且每条边有一个权值。现在让你删去其中的若干条边,使得这N个节点相互连通。当然有很多种不同的删法,现在让你找出一种删法,使得删除的边的权值和最大,如果不存在删法,使得这N个节点相联通,输出-1,否则,输出删除的最大边权和。

#include
#include
#include
using namespace std;
struct edge
{
    int u, v;
    int w;
    friend bool operator < (edge a, edge e)
    {
        return a.w part;
vector father(1000000, -1);
long findfather(long i)
{
    if (father[i] == -1) return i;
    else  return father[i] = findfather(father[i]);
}
void merge_union(long x, long y)
{
    long f1 = findfather(x);
    long f2 = findfather(y);
    father[f1] = f2;
}
long findmin(long n)
{
    sort(part.begin(), part.end());
    vector mst;
    long sum = 0;
    long x = 0;
    for (long i = 0; i> T;
    while (T--)
    {
        cin >> N >> M;
        long x,sum=0;
        for (long i = 0; i> ed.u >> ed.v >> ed.w;
            part.push_back(ed);
            sum += ed.w;
        }
        x = findmin(N);
        if (x == -1) cout <<  x << endl;
        else
            cout << sum-x << endl;
        part.clear();
        father.clear();
        father.resize(1000000, -1);
    }
    return 0;
}

 

你可能感兴趣的:(树状数组-并查集)