写在前面:生成树yyds!
题面
T1 种胡萝卜
坑太多暴力过不去!
用并查集!啪的一下就输出了!很快啊!
code:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define maxn 3000010
#define ll long long
using namespace std;
template<typename T>
inline void read(T &x){
x=0;bool flag=0;char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') flag=1;
for(;isdigit(c);c=getchar()) x=x*10+(c^48);
if(flag) x=-x;
}
const int mod=1000000007;
ll n,m,a,fa[maxn],ans;
bool flag[maxn];
int f(int x){
return fa[x]=(fa[x]==x)?x:f(fa[x]);
}
int main(){
read(n),read(m);
for(int i=0;i<=m;i++) fa[i]=i;
for(int i=1;i<=n;i++){
read(a);
ll fa1=f(a);
if(!fa1) continue;
ll fa2=f(fa1-1);
(ans+=i*fa1)%=mod;
if(fa1!=fa2) fa[fa1]=fa2;
}
printf("%lld
",ans);
return 0;
}
/*
5 8
7 7 1 6 1
*/
//42
/*
8 8
8 8 5 5 5 6 2 1
*/
//126
T2 sequence
贪心
数据范围很小啊 按右端点排排序然后暴力打flag,最后数数一共多少个flag就行了
code:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define maxn 1010
using namespace std;
template<typename T>
inline void read(T &x){
x=0;bool flag=0;char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') flag=1;
for(;isdigit(c);c=getchar()) x=x*10+(c^48);
if(flag) x=-x;
}
int n,c[maxn];
int ans,sum,ll=10010,rr=-1;
bool flag[maxn];
struct data{
int l,r,c;
bool friend operator < (data a,data b){
if(a.r!=b.r) return a.r<b.r;
return a.l<b.l;
}
}s[maxn];
int main(){
read(n);
for(int i=1;i<=n;i++){
read(s[i].l),read(s[i].r),read(s[i].c);
ll=min(ll,s[i].l),rr=max(rr,s[i].r);
}
// cout<<ll<<" "<<rr<<"*"<<endl;
sort(s+1,s+n+1);
// for(int i=1;i<=n;i++) cout<<s[i].l<<" "<<s[i].r<<endl;
for(int i=1;i<=n;i++){
sum=0;
for(int j=s[i].r;j>=s[i].l;j--){
if(flag[j]) sum++;
}
if(sum>=s[i].c) continue;
for(int j=s[i].r;j>=s[i].l;j--){
if(sum==s[i].c) break;
if(!flag[j]){
flag[j]=1;
sum++;
}
}
}
for(int i=ll;i<=rr;i++) if(flag[i]) ans++;
cout<<ans<<endl;
return 0;
}
/*
4
4 5 1
6 10 3
7 10 3
5 6 1
*/
//4
/*
4
4 5 2
5 6 2
6 10 5
7 10 4
*///7
T3 最小代价
听说有神仙把它看成最大代价了
至于做法,其实也就是横纵坐标分别排排序,然后跑最小生成树宛如板子但是考场上愣是没做出来
还有, pii 真好用!
code:
#include<iostream>
#include<cstdio>
#include<algorithm>
#define ll long long
#define pii pair<int,int>
#define fir first
#define sec second
#define maxn 200010
using namespace std;
template<typename T>
inline void read(T &x){
x=0; bool flag=0; char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') flag=1;
for(;isdigit(c);c=getchar()) x=x*10+(c^48);
if(flag) x=-x;
}
int n,m;
int siz[maxn],fa[maxn];
int sum=0,cnt=0;
pii x[maxn],y[maxn];
struct bcj{
void init(int n){
for(int i=1;i<=n;i++) fa[i]=i,siz[i]=1;
}
int f(int x){
return (fa[x]==x)?x:fa[x]=f(fa[x]);
}
void u(int x,int y,int z){//********
x=f(x);y=f(y);
if(x!=y){
fa[x]=y;
sum+=z;
siz[y]+=siz[x];
}
// if(x==y) return false;
// fa[x]=y;
// return true;
}
}s;
bool cmp (pii x,pii y){
return x.sec<y.sec;
}
struct edge{
int u,v,w;
bool friend operator < (edge a,edge b){
return a.w<b.w;
}
}e[maxn];
int main(){
read(n);
s.init(n);
for(int i=1;i<=n;i++) {
read(x[i].sec);read(y[i].sec);
x[i].fir=i,y[i].fir=i;
}
sort(x+1,x+n+1,cmp);
sort(y+1,y+n+1,cmp);
for(int i=1;i<=n-1;i++){
m++;
e[m].u=x[i].fir,e[m].v=x[i+1].fir,e[m].w=x[i+1].sec-x[i].sec;
m++;
e[m].u=y[i].fir,e[m].v=y[i+1].fir,e[m].w=y[i+1].sec-y[i].sec;
}
sort(e+1,e+m+1);
for(int i=1;i<=m;i++){
// if(s.u(e[i].u,e[i].v)){
// sum+=e[i].w;
// siz[s.f(e[i].v)]+=siz[s.f(e[i].u)];//****????
// }
s.u(e[i].u,e[i].v,e[i].w);
int fax=s.f(e[i].u),fay=s.f(fa[e[i].v]);
if(siz[fax]==n||siz[fay]==n){
cout<<sum<<endl;
break;
}
}
return 0;
}
/*
3
1 5
3 9
7 8
*/
//3