头更更更大
这个11月完就要去搞NOIP了。。。
11月10天也就3次测试。。。为保佑进省一我还是每次测试玩都写个总结。。
emmm。。。。。又是三题全炸。。。
第一题做过忘了,顺手摔了一个优先队列上去,85。后来发现两个队列就能解决。。
第二题桶排序,搞了一个半小时心态爆炸放弃了去搞T3,回来顺手乱打了个暴力,20。
第三题最小生成树,暴力跑,但是由于没有开long long爆零。。。否则30到手。。。
按理说205很轻松的。。。orz
下面面详细解答:
T1(85/100):Blash数集
problem
题意:一个数集,规定如果x在集合中,那么 2x+1,3x+1 也在集合中。现在给你初始值x,询问第n大的数是多少。
样例
输入
1 100
28 5437输出
418
900585
solution
当时知道是原题但是就是想不起来了。。。orz然后甩了个优先队列上去。
正解是用两个数组分别存储2x+1的项与3x+1的项,然后去去重就完事了。
T2(20/100):序列操作
problem
题意:给你一个数列,接下来要进行m次操作,每次操作要求你把数组中的c个正整数-1,问你最多能进行几次操作。
样例:
输入
3 5
1 2 5
1 2 3 2 1输出
3
solution
正解是二分,然而因为元素最大值不过1e4所以桶排序貌似跑的也不慢。。这里讲桶排序的。
相当于每次操作暴力模拟,如果桶中的元素少于要找的数,就把整个桶排序中的元素向下移一层(先把下面那层处理了再移);如果不少那就把需要找的数向下移一层就行。
论代码风格的简洁性的重要性。。。稍微改了下就是100。。。
T3(0/100):图
problem
题意
一个无向图,其中A条边的权值为k+x(每条边的权值由定值k与全局变量v决定),B条边的权值为k-x,而且这A,B条边分别能使整个图联通。询问对于不同的v,这个图的最小生成树的边权和是多少。
样例
输入
5 4 4 4
1 3 2
1 2 0
3 5 5
3 4 10
5 4 7
2 3 6
1 2 1000
3 4 1000
0
1
2
3输出
14
16
18
18
solution
30%随便乱搞,暴力Kruskal。
50%利用特殊数据,A边一定是最优的,直接按着A边建就行。
100%。。。还是自己去后面看DZY大佬的代码吧orz
感想
审题!!!多打暴力!!!沉住气!!!多练模板!!!
代码:
T1:
std.cpp
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
using namespace std;
inline int read()
{
int X=0,w=1; char ch=0;
while(ch<'0' || ch>'9') {if(ch=='-') w=-1;ch=getchar();}
while(ch>='0' && ch<='9') X=(X<<3)+(X<<1)+ch-'0',ch=getchar();
return X*w;
}
#define U_MAX 200
inline char *get_str(char *str)
{
fgets(str,U_MAX,stdin);
if(str[strlen(str)-1] == '\n')
str[strlen(str)-1] = '\0';
return str;
}
inline void write(int x)
{
if(x<0) putchar('-'),x=-x;
if(x>9) write(x/10);
putchar(x%10+'0');
}
const int kkk=4000000;
int top1,que1[kkk];
int top2,que2[kkk];
int a,n,m;
int main()
{
//freopen("blash.in","r",stdin);
//freopen("blash.out","w",stdout);
while(~scanf("%d%d",&a,&n))
{
int cnt1=1,cnt2=1;
if(n==1){cout<<a<<endl;continue;}
que1[top1=1]=2*a+1;
que2[top2=1]=3*a+1;
n-=1;
while(n--)
{
if(que1[cnt1]==que2[cnt2])
{
a=que1[cnt1];
que1[cnt1]=0;cnt1++;
que2[cnt2]=0;cnt2++;
}
else if(que1[cnt1]<que2[cnt2])
{
a=que1[cnt1];
que1[cnt1]=0;cnt1++;
}
else if(que1[cnt1]>que2[cnt2])
{
a=que2[cnt2];
que2[cnt2]=0;cnt2++;
}
que1[++top1]=2*a+1;que2[++top2]=3*a+1;
}
cout<<a<<endl;
}
}
T2
std.cpp
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
using namespace std;
inline int read()
{
int X=0,w=1; char ch=0;
while(ch<'0' || ch>'9') {if(ch=='-') w=-1;ch=getchar();}
while(ch>='0' && ch<='9') X=(X<<3)+(X<<1)+ch-'0',ch=getchar();
return X*w;
}
inline void write(int x)
{
if(x<0) putchar('-'),x=-x;
if(x>9) write(x/10);
putchar(x%10+'0');
}
const int kkk=10005;
int n,m,flag;
int h,s[kkk];
int sum[kkk];
int main()
{
//freopen("sequence.in","r",stdin);
//freopen("sequence.out","w",stdout);
n=read(); m=read(); flag=1;
for(int i=1;i<=n;i++)h=read(),sum[h]++,sum[0]=max(sum[0],h);
h=sum[0];
for(int i=1;i<=m;i++)
{
n=read();
int tot=0,pos=0;
for(int j=h;j>=1;j--)
{
if(tot+sum[j]>=n)
{pos=j+1;break;}
tot+=sum[j];
}
if(pos==0){cout<<i-1;return 0;}
int tmp=n-tot;
sum[pos-1]-=tmp;
sum[pos-2]+=tmp;
for(int j=pos;j<=h;j++)
{
sum[j-1]+=sum[j];
sum[j]=0;
}
}
cout<<m<<endl;
}
T3
std_50%.cpp
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
using namespace std;
typedef long long ll;
inline int read()
{
int X=0,w=1; char ch=0;
while(ch<'0' || ch>'9') {if(ch=='-') w=-1;ch=getchar();}
while(ch>='0' && ch<='9') X=(X<<3)+(X<<1)+ch-'0',ch=getchar();
return X*w;
}
#define U_MAX 200
inline char *get_str(char *str)
{
fgets(str,U_MAX,stdin);
if(str[strlen(str)-1] == '\n')
str[strlen(str)-1] = '\0';
return str;
}
inline void write(int x)
{
if(x<0) putchar('-'),x=-x;
if(x>9) write(x/10);
putchar(x%10+'0');
}
const int kkk=100005;
struct node{
int u,v,k,flag;
}side[4*kkk];
int fa[kkk];
inline int ga(int x){return ((fa[x]==x)?(x):(fa[x]=ga(fa[x])));}
int v;
bool compi(const node&a,const node&b){return (a.k+a.flag*v)<(b.k+b.flag*v);}
bool comp(const node&a,const node&b){return (a.k)<(b.k);}
int n,a,b,q,ans1,ans2,cnt1,cnt2;
ll get_ans1()
{
ll ans=0;
for(int i=1;i<=n;i++)fa[i]=i;
sort(side+1,side+a+b+1,compi);
for(int i=1;i<=a+b;i++)
{
int u=side[i].u;
int g=side[i].v;
if(ga(u)!=ga(g))
{
fa[ga(u)]=ga(g);
ans+=1LL*(side[i].k+side[i].flag*v);
}
}
return ans;
}
int main()
{
//freopen("mst.in","r",stdin);
//freopen("mst.out","w",stdout);
n=read();a=read();b=read();q=read();int flag=0;
for(int i=1;i<=a;i++)
{
side[i].u=read();
side[i].v=read();
side[i].k=read();
side[i].flag=1;
if(side[i].k>1e8)flag=1;
}
for(int i=1;i<=b;i++)
{
side[i+a].u=read();
side[i+a].v=read();
side[i+a].k=read();
side[i+a].flag=-1;
if(side[i+a].k<9*1e8||side[i+a].k>1e9)flag=1;
}
if(flag)
for(int i=1;i<=q;i++)
{
v=read();
cout<<get_ans1()<<endl;
}
else
{
int numy=0;
ll ans=0;
for(int i=1;i<=n;i++)fa[i]=i;
sort(side+1,side+a+1,comp);
for(int i=1;i<=a;i++)
{
int u=side[i].u;
int g=side[i].v;
if(ga(u)!=ga(g))
{
fa[ga(u)]=ga(g);
ans+=1LL*(side[i].k);
numy++;
}
}
for(int i=1;i<=q;i++)
{
v=read();
cout<<ans+1LL*numy*v<<endl;
}
}
}
std.cpp
#include<bits/stdc++.h>
using namespace std;
inline int read(){
char ch=getchar();int i=0,f=1;
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch)){i=(i<<1)+(i<<3)+ch-'0';ch=getchar();}
return i*f;
}
inline void W(long long x){
static int buf[50];
if(!x){putchar('0');return;}
if(x<0){putchar('-');x=-x;}
while(x){buf[++buf[0]]=x%10;x/=10;}
while(buf[0])putchar(buf[buf[0]--]+'0');
}
const int Maxn=1e5+50;
const int INF=0x3f3f3f3f;
int n,Acnt,Bcnt,q,anc[Maxn];
long long ans[Maxn],sum;
struct node{
node *lc,*rc,*fa,*mxid;
int val,mx,x,y,revtag;
inline void rev(){
revtag^=1;
swap(lc,rc);
}
inline void pushdown(){
if(!revtag)return;
if(lc)lc->rev();
if(rc)rc->rev();
revtag^=1;
}
inline void upt(){
mxid=this;mx=val;
if(lc&&lc->mx>mx)mxid=lc->mxid,mx=lc->mx;
if(rc&&rc->mx>mx)mxid=rc->mxid,mx=rc->mx;
}
}Pool[Maxn<<2],*pool=Pool,*pos[Maxn];
inline node* newnode(int v,int x,int y){
++pool;
pool->lc=NULL;pool->rc=NULL;pool->fa=NULL;
pool->val=v;pool->mx=v;pool->mxid=pool;
pool->x=x;pool->y=y;
return pool;
}
struct E{
int x,y,w;
friend inline bool operator <(const E &a,const E &b){
return a.w<b.w;
}
}A[Maxn<<1],B[Maxn<<1];
struct E2{
int x,y,w,low,rpc;
inline bool operator =(const E &b){
x=b.x,y=b.y,w=b.w;
}
}Bnow[Maxn];
struct Q{
int v,id;
}qry[Maxn];
inline bool cmpv(const Q &a,const Q &b){return a.v<b.v;}
inline bool cmpw(const E2 &a,const E2 &b){return a.w<b.w;}
inline bool cmplow(const E2 &a,const E2 &b){return a.low<b.low;}
inline int getanc(int x){return (anc[x]==x)?(x):(anc[x]=getanc(anc[x]));}
inline bool isroot(node *x){
return !x->fa||(x->fa->lc!=x&&x->fa->rc!=x);
}
inline bool which(node *x){
return x->fa->lc==x;
}
inline void rotate(node *x){
node *y=x->fa,*z=y->fa;
if(!isroot(y))(z->lc==y?z->lc:z->rc)=x;
x->fa=z;y->fa=x;
if(y->lc==x){
node *b=x->rc;
x->rc=y;
y->lc=b;
if(b)b->fa=y;
}else{
node *b=x->lc;
x->lc=y;
y->rc=b;
if(b)b->fa=y;
}
y->upt();x->upt();
}
inline void splay(node *x){
static node* que[Maxn];
static int tail;
que[tail=1]=x;
for(node* y=x;!isroot(y);y=y->fa)que[++tail]=y->fa;
for(int i=tail;i>=1;i--)que[i]->pushdown();
while(!isroot(x)){
node *y=x->fa;
if(!isroot(y)){
if(which(y)^which(x))rotate(y);
else rotate(x);
}
rotate(x);
}
}
inline void access(node *x){
for(node *y=NULL;x;y=x,x=x->fa){
splay(x);x->rc=y;x->upt();
if(y)y->fa=x;
}
}
inline void makeroot(node *x){
access(x);splay(x);x->rev();
}
inline node* findmx(node *x,node *y){
makeroot(x);access(y);splay(y);
return y->mxid;
}
inline void Cut(node *x,node *y){
makeroot(x);access(y);splay(y);
y->lc->fa=NULL;y->lc=NULL;y->upt();
}
inline void Link(node *x,node *y){
makeroot(x);x->fa=y;
}
int main(){
n=read(),Acnt=read(),Bcnt=read(),q=read();
for(int i=1;i<=Acnt;i++){
A[i].x=read(),A[i].y=read(),A[i].w=read();
}
for(int i=1;i<=Bcnt;i++){
B[i].x=read(),B[i].y=read(),B[i].w=read();
}
sort(A+1,A+Acnt+1);sort(B+1,B+Bcnt+1);
for(int i=1;i<=n;i++)pos[i]=newnode(-INF,0,0);
int head=1;
for(int i=1;i<=n;i++)anc[i]=i;
for(int i=1;i<n;i++){
while(getanc(A[head].x)==getanc(A[head].y))++head;
anc[getanc(A[head].x)]=getanc(A[head].y);
node *t=newnode(A[head].w,A[head].x,A[head].y);
Link(pos[A[head].x],t);Link(pos[A[head].y],t);
sum+=A[head].w;++head;
}
head=1;int tot=0;
for(int i=1;i<=n;i++)anc[i]=i;
for(int i=1;i<n;i++){
while(getanc(B[head].x)==getanc(B[head].y))++head;
anc[getanc(B[head].x)]=getanc(B[head].y);
Bnow[i]=B[head++];
}
sort(Bnow+1,Bnow+tot+1,cmpw);
for(int i=1;i<n;i++){
node *t=findmx(pos[Bnow[i].x],pos[Bnow[i].y]);
if(t->val<=-INF){Bnow[i].low=INF;}
else{
Bnow[i].low=(Bnow[i].w-t->val+1)/2;
Bnow[i].rpc=t->val;
Cut(t,pos[t->x]);Cut(t,pos[t->y]);
t=newnode(-INF,0,0);
Link(pos[Bnow[i].x],t);Link(pos[Bnow[i].y],t);
}
}
sort(Bnow+1,Bnow+n,cmplow);
for(int i=1;i<=q;i++)qry[i].v=read(),qry[i].id=i;
sort(qry+1,qry+q+1,cmpv);
int cntB=0;head=0;
for(int i=1;i<=q;i++){
while(head<n-1&&Bnow[head+1].low<=qry[i].v){
++head;cntB++;
sum+=Bnow[head].w;sum-=Bnow[head].rpc;
}
ans[qry[i].id]=sum+1ll*(n-1-2*cntB)*qry[i].v;
}
for(int i=1;i<=q;i++){
W(ans[i]);putchar('\n');
}
}