1001题就是直接模拟就好,但是有坑点,就是后面给的开门的时间点需要排下序,wa到比赛快结束了菜反应过来,可能也是第一次做这种比赛有点紧张吧;
#include "iostream"
#include "cstdio"
#include "cstdlib"
#include "cstring"
#include "climits"
#include "queue"
#include "cmath"
#include "map"
#include "set"
#include "stack"
#include "vector"
#include "sstream"
#include "algorithm"
using namespace std;
const int inf=1e8;
const int maxn=150000+100;
typedef long long ll;
typedef unsigned long long ull;
struct person
{
char name[300];
int v,id;
bool operator < (const person & rhs) const
{
if(v!=rhs.v)
return v<rhs.v;
else
return id>rhs.id;
}
};
person a[maxn];
int k,m,q,t,p;
int ans[maxn];
int que[maxn];
struct data
{
int t,p;
}mm[maxn];
bool cmp(data left,data right)
{
return left.t<right.t;
}
int main()
{
//ios::sync_with_stdio(false);
// freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int T;
scanf("%d",&T);
priority_queue<person> pq;
while(T--)
{
while(!pq.empty())
pq.pop();
scanf("%d%d%d",&k,&m,&q);
for(int i=1;i<=k;i++)
{
scanf("%s%d",a[i].name,&a[i].v);
a[i].id=i;
}
int last=1;
int cnt=0;
for(int i=1;i<=m;i++)
scanf("%d%d",&mm[i].t,&mm[i].p);
sort(mm+1,mm+m+1,cmp);
for(int i=1;i<=m;i++)
{
for(int j=last;j<=mm[i].t;j++)
pq.push(a[j]);
last=mm[i].t+1;
for(int j=1;j<=mm[i].p&&!pq.empty();j++)
{
person tmp=pq.top();
ans[++cnt]=tmp.id;
pq.pop();
}
}
if(last<=k)
{
for(int j=last;j<=k;j++)
pq.push(a[j]);
}
int maxv=0;
for(int i=1;i<=q;i++)
{
scanf("%d",&que[i]);
maxv=max(maxv,que[i]);
}
for(cnt++;cnt<=maxv;cnt++)
{
person tmp=pq.top();
ans[cnt]=tmp.id;
pq.pop();
}
for(int i=1;i<=q;i++)
{
printf("%s",a[ans[que[i]]].name);
if(i!=q)
printf(" ");
}
printf("\n");
}
return 0;
}
1002题要先根据条件删除一下点,也就是度为一的点,同时与之相连的点的度数也要减1,知道再也找不到度为一的点了;然后就是用并查集了,记录每个连通块中点的数目以及该连通块中点权的和,注意要用long long,不然怎么死的都不知道;因为long long 的原因知道快结束了才搞定,日了dog了。。。。
/*****************************************
Author :Crazy_AC(JamesQi)
Time :2015
File Name :
*****************************************/
// #pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <sstream>
#include <string>
#include <stack>
#include <queue>
#include <deque>
#include <vector>
#include <map>
#include <set>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <limits.h>
using namespace std;
#define MEM(a,b) memset(a,b,sizeof a)
#define pk push_back
template<class T> inline T Get_Max(const T&a,const T&b){return a < b?b:a;}
template<class T> inline T Get_Min(const T&a,const T&b){return a < b?a:b;}
typedef long long ll;
typedef pair<int,int> ii;
const int inf = 1 << 30;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const int maxn = 1e5 + 10;
ii E[maxn];
int val[maxn];
int F[maxn];
int in[maxn];
int cnt[maxn];
ll sum[maxn];
int n,m;
int Find(int x){
if (F[x] == x) return x;
else return F[x] = Find(F[x]);
}
int main()
{
// ios::sync_with_stdio(false);
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
int T;
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
for (int i = 1;i <= n;++i){
scanf("%lld",&sum[i]);
F[i] = i;
cnt[i] = 1;
}
MEM(in, 0);
for (int i = 1;i <= m;++i){
scanf("%d%d",&E[i].first,&E[i].second);
in[E[i].first]++;
in[E[i].second]++;
}
bool flag = true;
while(flag){
flag = false;
for (int i = 1;i <= m;++i){
if (in[E[i].first] == 0 || in[E[i].second] == 0) continue;
if ((in[E[i].first] != 0 && in[E[i].second] != 0) && (in[E[i].first] < 2 || in[E[i].second] < 2)){
in[E[i].first]--;
in[E[i].second]--;
flag = true;
}
else continue;
}
}
// MEM(sum ,0);
// MEM(cnt, 0);
for (int i = 1;i <= m;++i){
if (in[E[i].first] && in[E[i].second]){
int t1 = Find(E[i].first);
int t2 = Find(E[i].second);
if (t1 != t2){
F[t1] = t2;
cnt[t2] += cnt[t1];
sum[t2] += sum[t1];
}
}
}
ll ans = 0;
for (int i = 1;i <= n;++i){
if (!in[i]) continue;
if (F[i] == i && cnt[i] > 1 && cnt[i] & 1)
ans += sum[i];
}
printf("%lld\n",ans);
}
return 0;
}
1005题也是一个并查集的简单应用,因为某种不想吐槽的原因导致比赛的时候没做出来,原因就不说了;
这里注意人可以在每个点休息,但是不能在路上待的时间超过limit,用了一点贪心点思想,如果limit1 < limit2,
那么使用与limit1的情况也适用于limit2的情况;所以对所有的limit进行排序,再使用并查集求连通块中点的数目,
由于是求点对<u,v> 与 <v,u>是不同的;最后对于该limit的点对总和就应该是sum(cnt[i] * (cnt[i] - 1));
最后对应输出就好了;
/*****************************************
Author :Crazy_AC(JamesQi)
Time :2015
File Name :
*****************************************/
// #pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <sstream>
#include <string>
#include <stack>
#include <queue>
#include <deque>
#include <vector>
#include <map>
#include <set>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <limits.h>
using namespace std;
#define MEM(a,b) memset(a,b,sizeof a)
#define pk push_back
template<class T> inline T Get_Max(const T&a,const T&b){return a < b?b:a;}
template<class T> inline T Get_Min(const T&a,const T&b){return a < b?a:b;}
typedef long long ll;
typedef pair<int,int> ii;
const int inf = 1 << 30;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const int N = 2e4 + 10;
const int M = 1e5 + 10;
int F[N];
int cnt[N];
int n,m,q;
struct Edge{
int u,v,w;
bool operator < (const Edge& b)const{
return w < b.w;
}
}E[M];
int Find(int x){
if (F[x] == x) return x;
else return F[x] = Find(F[x]);
}
int main()
{
// ios::sync_with_stdio(false);
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
int T;
scanf("%d",&T);
while(T--){
scanf("%d%d%d",&n,&m,&q);
for (int i = 1;i <= n;++i) {
F[i] = i;
cnt[i] = 1;
}
for (int i = 1;i <= m;++i){
scanf("%d%d%d",&E[i].u,&E[i].v,&E[i].w);
}
sort(E + 1,E + m + 1);
ii rec[N];
for (int i = 1;i <= q;++i){
scanf("%d",&rec[i].first);
rec[i].second = i;
}
sort(rec + 1,rec + 1 + q);
int out[N];
int last = 1;
for (int i = 1;i <= q;++i){
int limit = rec[i].first;
// int cnt = 1;
int j;
for (j = last;j <= m;++j){
if (E[j].w > limit) break;
int t1 = Find(E[j].u);
int t2 = Find(E[j].v);
if (t1 != t2){
F[t1] = t2;
cnt[t2] += cnt[t1];
}
}
last = j;
ll tmp = 0;
for (j = 1;j <= n;++j){
if (F[j] == j && cnt[j] > 1)
tmp += cnt[j] * (cnt[j] - 1) ;
}
out[rec[i].second] = tmp;
}
for (int i = 1;i <= q;++i)
printf("%d\n",out[i]);
}
return 0;
}
1006题就是字符串的最大表示法模板题;
#include <iostream>
#include <cstdio>
#include <complex>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <cctype>
typedef unsigned long long ull ;
typedef long long ll ;
using namespace std ;
const double eps = 1e-10 , pi = acos(-1.0) ;
const int maxn = 20000 + 5 ;
const int maxm = 200000 + 5 ;
const int inf = 0x3f3f3f3f ;
const ll mod = 1e9 + 7 ;
const ull C = 123 ;
char s[maxn] , ss[maxn*2] ;
int n , T ;
ull Hash[maxn*2] , P ;
int maxPresent( char *s , int n )
{
int i = 0 , j = 1 , k = 0 , t ;
while( i < n && j < n && k < n )
{
t = s[(i+k)%n] - s[(j+k)%n] ;
if( !t ) k++ ;
else
{
if( t < 0 ) i += k+1 ;
else j += k+1 ;
if( i == j ) j++ ;
k = 0 ;
}
}
return min(i,j) ;
}
void getHash( char *s , int n )
{
Hash[n] = 0 ;
for( int i = n-1 ; i >= 0 ; i-- )
{
Hash[i] = Hash[i+1] * C + s[i] ;
}
}
ull getCode( int pos , int n )
{
return Hash[pos] - Hash[pos+n] * P ;
}
int maxIndex( char *s , int n , int k )
{
getHash(s,n*2) ; P = 1 ;
for( int i = 0 ; i < n ; i++ ) P *= C ;
ull code = getCode(k,n) ;
for( int i = n-1 ; i > k ; i-- )
{
if( getCode(i,n) == code ) return i ;
}
return k ;
}
int main()
{
scanf( "%d" , &T ) ;
while( T-- )
{
scanf( "%d%s" , &n , s ) ;
for( int i = 0 ; i < n ; i++ ) ss[i] = ss[i+n] = s[n-i-1] ;
int a = maxPresent(s,n) , b = maxPresent(ss,n) ;
b = maxIndex(ss,n,b) ;
int k = 0 , f = 0 ;
for( int i = a , j = b ; k < n ; k++ , i = (i+1)%n , j = (j+1)%n )
{
if( s[i] == ss[j] ) continue ;
else
{
if( s[i] < ss[j] ) f = 1 ;
break ;
}
}
a = a+1 ;
b = n-b ;
if( k == n )
{
if( a > b ) printf( "%d %d\n" , b , 1 ) ;
else printf( "%d %d\n" , a , 0 ) ;
}
else
{
if( f == 1 ) printf( "%d %d\n" , b , 1 ) ;
else printf( "%d %d\n" , a , 0 ) ;
}
}
return 0 ;
}
1008就是裸的二叉树重建,然后dfs输出路径;这种题一定要注意界限的问题RE了7发ORZ。。。
/*****************************************
Author :Crazy_AC(JamesQi)
Time :2015
File Name :
*****************************************/
// #pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <sstream>
#include <string>
#include <stack>
#include <queue>
#include <deque>
#include <vector>
#include <map>
#include <set>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <limits.h>
using namespace std;
#define MEM(a,b) memset(a,b,sizeof a)
#define pk push_back
template<class T> inline T Get_Max(const T&a,const T&b){return a < b?b:a;}
template<class T> inline T Get_Min(const T&a,const T&b){return a < b?a:b;}
typedef long long ll;
typedef pair<int,int> ii;
const int inf = 1 << 30;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const int maxn = 1e5 + 10;
int n,q;
int ls[maxn];
int rs[maxn];
int val[maxn];
int top;
int new_node(int x){
++top;
ls[top] = rs[top] = 0;
val[top] = x;
return top;
}
int insert(int rt,int num){
if (!val[rt]) return new_node(num);
if (num < val[rt]) ls[rt] = insert(ls[rt],num);
else rs[rt] = insert(rs[rt],num);
return rt;
}
void Query(int rt,int num){
if (num < val[rt]) {
putchar('E');
Query(ls[rt],num);
}
else if (num > val[rt]){
putchar('W');
Query(rs[rt],num);
}
}
int main()
{
// ios::sync_with_stdio(false);
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
int T;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
int x;
MEM(val, 0);
top = 0;
for (int i = 1;i <= n;++i){
scanf("%d",&x);
insert(1,x);
}
scanf("%d",&q);
while(q--){
scanf("%d",&x);
Query(1,x);
printf("\n");
}
}
return 0;
}
1007题就是裸的RMQ,用线段树和ST都是可以的;
/*****************************************
Author :Crazy_AC(JamesQi)
Time :2015
File Name :
*****************************************/
// #pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <sstream>
#include <string>
#include <stack>
#include <queue>
#include <deque>
#include <vector>
#include <map>
#include <set>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <limits.h>
using namespace std;
#define MEM(a,b) memset(a,b,sizeof a)
#define pk push_back
template<class T> inline T Get_Max(const T&a,const T&b){return a < b?b:a;}
template<class T> inline T Get_Min(const T&a,const T&b){return a < b?a:b;}
typedef long long ll;
typedef pair<int,int> ii;
const int inf = 1 << 30;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const int maxn = 1010;
int T,n,Q;
int MAX[maxn * 3];
void Built(int rt,int l,int r){
if (l == r){
scanf("%d",&MAX[rt]);
return ;
}
int mid = (l + r) >> 1;
Built(rt << 1,l,mid);
Built(rt << 1 | 1,mid + 1,r);
MAX[rt] = Get_Max(MAX[rt << 1],MAX[rt << 1 | 1]);
}
int Query(int rt,int L,int R,int l,int r){
if (l <= L && R <= r) return MAX[rt];
int mid = (L + R) >> 1;
int ret = 0;
if (l <= mid) ret = Get_Max(ret,Query(rt << 1,L,mid,l,r));
if (r > mid) ret = Get_Max(ret,Query(rt << 1 | 1,mid + 1,R,l,r));
return ret;
}
int main()
{
// ios::sync_with_stdio(false);
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
scanf("%d",&T);
while(T--){
MEM(MAX, 0);
scanf("%d",&n);
Built(1,1,n);
int a,b;
scanf("%d",&Q);
while(Q--){
scanf("%d%d",&a,&b);
printf("%d\n",Query(1,1,n,a,b));
}
}
return 0;
}
1010Lcase + CRT模板题,只是要注意中间结果爆long long,所以此时我们就用了快速幂边乘边取摸,最后返回值也要先取摸;
/*****************************************
Author :Crazy_AC(JamesQi)
Time :2015
File Name :
*****************************************/
// #pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <sstream>
#include <string>
#include <stack>
#include <queue>
#include <deque>
#include <vector>
#include <map>
#include <set>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <limits.h>
using namespace std;
#define MEM(a,b) memset(a,b,sizeof a)
#define pk push_back
template<class T> inline T Get_Max(const T&a,const T&b){return a < b?b:a;}
template<class T> inline T Get_Min(const T&a,const T&b){return a < b?a:b;}
typedef long long ll;
typedef pair<int,int> ii;
const int inf = 1 << 30;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const int N = 1e5 + 10;
const int M = 1e5 + 10;
ll n,m,k;
ll a[12],mm[12];
ll Quick_Mod(ll x,ll y,ll p){
ll rec = 1;
x %= p;
while(y){
if (y & 1) rec = rec * x % p;
y >>= 1;
x = x * x % p;
}
return rec;
}
ll C(ll n,ll m,ll p){
if (m > n) return 0;
ll ans = 1;
for (int i = 1;i <= m;++i){
ll a = (n + i - m) % p;
ll b = i % p;
ans = ans * (a * Quick_Mod(b,p - 2,p) % p) % p;
}
return ans;
}
ll Lucas(ll n,ll m, ll p){
if (m == 0) return 1;
return C(n % p,m % p , p) * Lucas(n / p,m / p,p) % p;
}
ll Extend_Euclid(ll a,ll b,ll& x,ll& y){
ll d;
if (b == 0){
x = 1;
y = 0;
return a;
}
d = Extend_Euclid(b, a % b,y,x);
y -= a / b * x;
return d;
}
ll mod_mul(ll a,ll b,ll mod){
ll ret = 0;
while(b){
if (b & 1) ret = (ret + a) % mod;
a = (a + a) % mod;
b >>= 1;
}
return ret;
}
ll CRT(){
ll d,x,y,tmp,M,ret;
ret = 0;
M = 1;
for (int i = 0;i < k;i++)
M *= mm[i];
for (int i = 0;i < k;++i){
tmp = M / mm[i];
d = Extend_Euclid(mm[i],tmp,x,y);
ll temp = mod_mul(y,tmp,M);
temp = mod_mul(temp,a[i],M);
ret = (ret + temp) % M;
}
return (M + ret) % M;
}
int main()
{
// ios::sync_with_stdio(false);
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
int T;
cin >> T;
while(T--){
cin >> n >> m >> k;
for (int i = 0;i < k;++i){
cin >> mm[i];
a[i] = Lucas(n,m,mm[i]);
}
cout << CRT() << endl;
}
return 0;
}
总结:虽然才学习一年,很多知识点掌握得都不够,原因有多总,来自学校和学长还有队里面的就不说了;
主要还是自己跟着不良风气走歪了,没能按照自己预定的计划进行训练,可能也是上大学后自己,
一个人,没有人管着,所以时间安排也是一团糟糕;但愿后面能静心做自己的事,不在受他人影响,
从来都是坚信,努力就会成功;做自己的也才是最对得起自己;
ps:这场网赛糟糕透了,,,后面继续努力,调整状态;