这大概是我唯一有用的一篇文章
CSP
T1
特殊情况卡掉一切格里高利;40pts
#include<iostream>
#include<cstdio>
using namespace std;
const int T=146097;//周期
const int P=150000;//比周期略大一些的预处理范围
const int baodi=2299160;//用这个来40分保底
long long y,m,d,t,q,ans,kkk;//不用long long见90
int num[15]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int NUM[15]={0,31,29,31,30,31,30,31,31,30,31,30,31};
bool ok(int a)
{
if (a%400==0)return 1;
if (a%4==0&&a%100!=0)return 1;
return 0;
}
int sum(int a,bool ry)
{
if(ry) return NUM[a];
else return num[a];
}
void cal(int ru,int n){
m=1;n+=1;
if(ru==0)
{
while(n>0)
n-=NUM[m++];
if(n<=0)
n+=NUM[--m];
printf("%d %d ",n,m);
return;
}
while(n>0)
n-=num[m++];
if(n<=0)
n+=num[--m];
printf("%d %d ",n,m);
return;
}
int yy1[P],mm1[P],dd1[P];
void init()
{
int MM,YY,DD;
mm1[1]=MM=10,yy1[1]=YY=1582;dd1[1]=DD=15;
for (int i=2;i<=T;i++)
{
DD++;
if (DD>sum(MM,ok(YY)))DD=1,MM++;
if (MM>12)MM=1,YY++;
mm1[i]=MM,yy1[i]=YY,dd1[i]=DD;
}
}
int main()
{
//freopen("julian.in","r",stdin);
//freopen("julian.out","w",stdout);
scanf("%lld",&q);
init();
for(int i=1;i<=q;i++){
y=-4712;
scanf("%lld",&t);
if(t<=baodi){
ans=4*(t/1461);
y+=ans;
t-=(ans/4)*1461;
while(t>365)
{
if(t>=731) {
y++;t-=365;}
if(t>=366&&t<731){
t-=366;y++;break;}
}
}
else{
ans=t;
ans-=baodi;
int Y=(ans/T)*400;ans%=T;
if(ans==0) ans=T,Y-=400;
m=mm1[ans],d=dd1[ans],y=Y+yy1[ans];
printf("%lld %lld %lld\n",d,m,y);
continue;
}
if(y<=1582&&y%4==0) cal(0,t);
else if(y<=1582&&y%4!=0) cal(1,t);
else if(y>1582&&(y%4==0&&y%100!=0||y%400==0)) cal(0,t);
else cal(1,t);
if(y<=0) printf("%lld BC\n",-y+1);
else printf("%lld\n",y);
}
return 0;
}
T2
完全没想出q没有用
然后我还不熟STL的数据结构!得到40pts
#include <cstdio>
#include <iostream>
#include <cstring>
#include <vector>
#define ll long long
#define ull unsigned long long
const int N=1e8+2;
using namespace std;
int n, m, c, k, cnt;
bool v[N];
ull a, p, q;
ull ans=1, res;
int main() {
//freopen("zoo.in","r",stdin);
//freopen("zoo.out","w",stdout);
scanf("%d%d%d%d",&n,&m,&c,&k);
cnt = k;
if (!n && !m && k==64) {
printf("18446744073709551616");
return 0;
}
for (int i = 1; i <= n; i++) {
scanf("%llu",&a);
res |= a;
}
for (int i = 0; i < m; i++) {
scanf("%d%d",&p,&q);
if (!((res>>p)&1) && !v[p]) {
cnt--;
v[p] = 1;
}
}
if(cnt) {
ans=ans<<(cnt-1);
ans*=2;
}
printf("%llu",ans-n);
return 0;
}
右移求 2 ^ 64 2\quad\hat{}\quad64 2^64是1 具体可自行尝试
T3&T4
我连暴力都卡不出来
我的算法板子
NOIP前打的,完全没用;
想但没打字符串虽但迟到
数学
扩欧
#include<bits/stdc++.h>
using namespace std;
int a,b,c,d,x,y,t;
void exgcd(int a,int b,int &d,int &x,int &y){
if(!b){x=1,y=0;return;}
exgcd(b,a%b,d,y,x);
y-=(a/b)*x;
}
int main()
{
scanf("%d%d%d",&a,&b,&c);
exgcd(a,b,d,x,y);
if(c%d==0)
{
x*=c/d;
t=b/d;
t=abs(t);
x=(x%t+t)%t;
printf("%d\n",x); //通解 最小正整数
printf("%d\n",(c-a*x)/b);
}
return 0;
}
图论
建边
void add(int u,int v) {
E[tot].v = v;
E[tot].next = head[u];
head[u] = tot++;
}
遍历
void dfs(int u)
{
int i;
vist[u]=1;
for(i=head[u];i;i=E[i].next)
{
int to=E[i].v;
if(vist[to]==0)
dfs(to);
}
}
堆优化
//第一关键字为dis,第二关键字为pos
std::priority_queue<node> q;
inline void dijkstra()
{
dis[s] = 0;
q.push( ( node ){0, s} );
while( !q.empty() )
{
node tmp = q.top();
q.pop();
int x = tmp.pos, d = tmp.dis;
if( vis[x] )
continue;
vis[x] = 1;
for( int i = head[x]; i; i = e[i].next )
{
int y = e[i].to;
if( dis[y] > dis[x] + e[i].dis )
{
dis[y] = dis[x] + e[i].dis;
if( !vis[y] )
{
q.push( ( node ){dis[y], y} );
}
}
}
}
}
双连通分量
int dfs(int u,int fa) {
low[u]=dfn[u]=++clock;
s.push(u);
for(int t=head[u]; t!=-1; t=E[t].next) {
int v=E[t].v;
if(!dfn[v]) {
int lowv=dfs(v,u);
low[u]=min(low[u],lowv);
if(lowv>=dfn[u]) {
bc++;
bcc[bc].clear();
int tmp=-1;
while(!s.empty()) {
tmp=s.top();
s.pop();
bcc[bc].push_back(tmp);
if(tmp==v)break;
}
bcc[bc].push_back(u);
}
} else if(dfn[v]<dfn[u]&&fa!=v) {
low[u]=min(low[u],dfn[v]);
}
}
return low[u];
}
LCA
void Init() {
int a,b;
scanf("%d",&n);
flag=0;
for(int i=1; i<=n; i++) {
head[i].clear();
Que[i].clear();
f[i]=i;
r[i]=1;
ancestor[i]=0;
indegreen[i]=0;
vis[i]=0;
}
for(int i=1;i<n;i++){
scanf("%d%d",&a,&b);
head[a].push_back(b);
indegreen[b]++;
}
scanf("%d%d",&a,&b);
Que[a].push_back(b);
Que[b].push_back(a);
}
int Find(int u) {
if(f[u]==u) return f[u];
else f[u]=Find(f[u]);
return f[u];
}
void Union(int v,int u) {
int a,b;
a=Find(v);
b=Find(u);
if(a==b) return;
if(r[a]<=r[b]) {
f[a]=b;
r[b]+=r[a];
} else {
f[b]=a;
r[a]+=r[b];
}
}
void LCA(int k) {
int size;
size=head[k].size();
for(int i=0; i<size; i++) {
if(flag) break;
LCA(head[k][i]);
Union(k,head[k][i]);
ancestor[Find(k)]=k;
}
vis[k]=1;
size=Que[k].size();
for(int i=0; i<size; i++)
if(vis[Que[k][i]]) {
flag=1;
printf("%d\n",ancestor[Find(Que[k][i])]);
return;
}
}
NOIP
分数:
60
+
30
=
90
60+30=90
60+30=90
但是about T1
- 补全了long long还是60
- 改写了__int 128还是60
- 听说能涨分,把lcm先除后乘,还是60
所以就不遗憾了叭(下面的码改过了,反正分都一样)
T1
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int M=1e5+5;
#define ll __int128
struct edge{
int v,next;
}E[M*10];
ll gcd(ll a,ll b)
{
if(b==0) return a;
return gcd(b,a%b);
}
inline void print(__int128 x){
if(x < 0){
x = -x ;
putchar('-');
}
if(x > 9){
print(x/10);
}
putchar(x%10+'0');
}
ll a,b,cnt,A,B,zi,mu,n,m;
ll f1[M],f2[M],head[M],ind[M],outd[M];
void add(ll u,ll v)
{
E[cnt].v=v;
E[cnt].next=head[u];
head[u]=cnt++;
}
void dfs(ll u)
{
for(int i=head[u];i!=-1;i=E[i].next)
{
int to=E[i].v;
if(f2[to]==0) {
f1[to]=f1[u];
f2[to]=f2[u]*outd[u];
}
else{
A=f2[to],B=f2[u]*outd[u];
int lcm=A/gcd(A,B)*B;
mu=lcm;
zi=mu*f1[u]/B+mu*f1[to]/f2[to];
a=gcd(zi,mu);
f1[to]=zi/a;f2[to]=mu/a;
}
dfs(to);
}
if(outd[u]) f1[u]=0,f2[u]=0;
return;
}
int main()
{
//freopen("water.in","r",stdin);
//freopen("water.out","w",stdout);
scanf("%lld%lld",&n,&m);
memset(head,-1,sizeof(head));
for(int i=1;i<=n;i++)
{
scanf("%lld",&outd[i]);
for(int j=1;j<=outd[i];j++)
{scanf("%lld",&b);
add(i,b);
ind[b]++;}
}
for(int i=1;i<=n;i++)
if(ind[i]==0) add(0,i);
f1[0]=m;f2[0]=1;outd[0]=m;
dfs(0);
for(int i=1;i<=n;i++)
if(outd[i]==0){
a=gcd(f1[i],f2[i]);
f1[i]=f1[i]/a;f2[i]=f2[i]/a;
print(f1[i]);
printf(" ");
print(f2[i]);
printf("\n");
}
return 0;
}
注:这根本就不是topsort,其实它是可以的
(所以T1其实相当于没有算法吗)
T2&T3
我连暴力都卡不出来
T4
显然的暴力
但是为什么里面有一个-1啊
我这相当于亏了10分
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int M=1e5+5;
const int mod=1e9+7;
int n,k,step,flag;
int c[M],d[M];
int now[10],w[10],st[10];
bool judge()
{
for(int i=1;i<=k;i++)
if(now[i]>w[i]||now[i]<1) return false;
return true;
}
bool judge2()
{
for(int i=1;i<=k;i++)
if(now[i]!=st[i]) return false;
return true;
}
void cal()
{
memcpy(now,st,sizeof(now));
while(judge()){
for(int i=1;i<=n;i++)
{
now[c[i]]+=d[i];
step++;
if(!judge()) return;
}
if(judge2()) {flag=1;return;}
}
}
void sth(int dep)
{
if(dep==k+1) {cal();return;}
for(int i=1;i<=w[dep];i++) {
st[dep]=i;
sth(dep+1);
}
return;
}
int main()
{
//freopen("walk.in","r",stdin);
//freopen("walk.out","w",stdout);
scanf("%d%d",&n,&k);
for(int i=1;i<=k;i++)
scanf("%d",&w[i]);
for(int i=1;i<=n;i++)
scanf("%d%d",&c[i],&d[i]);
sth(1);if(flag==1) step=-1;
printf("%d",step);
return 0;
}
没省一,大概率AFO~