A-digits 2
直接n个n拼起来就好了。。。
#include <bits/stdc++.h>
using namespace std;
int main(){
int T ; cin >> T;
while(T--){int n; cin >> n; for(int i=1;i<=n;i++) cout<<n; cout<<endl;}
return 0;
}
B-generator 1
写高精度显然超时
快速幂的时候改成十进制快速幂就行了
矩阵的乘法并不满足欧拉定理
#include <bits/stdc++.h>
#define rep(i,a,b) for(ll i=(a);i<=(b);i++)
using namespace std;
typedef long long ll;
inline ll read()
{
ll p=0; ll f=1; char ch=getchar();
while(ch<'0' || ch>'9'){if(ch=='-') f=-1; ch=getchar();}
while(ch>='0' && ch<='9'){p=p*10+ch-'0'; ch=getchar();}
return p*f;
}
ll x0,x1,a,b,n,mod;
struct node
{
ll a[3][3];
node(){memset(a,0,sizeof(a));}
friend node operator * (node x,node y)
{
node z;
for(ll i=1;i<=2;i++) for(ll j=1;j<=2;j++) for(ll k=1;k<=2;k++)
z.a[i][j] = (z.a[i][j] + x.a[i][k] * y.a[k][j] % mod) % mod;
return z;
}
friend node operator ^ (node x,ll k)
{
node z; for(ll i=1;i<=2;i++) z.a[i][i] = 1;
while(k)
{
if(k&1)
{
z=z*x;
}
x=x*x;
k>>=1;
}return z;
}
}s,p,q;
char ss[1000010];
ll num[1000010]; ll l;
node calc(node p)
{
node z; for(ll i=1;i<=2;i++) z.a[i][i] = 1;
for(ll i=1;i<=l;i++)
{
z = z*(p^num[i]);
p = p^(10ll);
}
return z;
}
int main()
{
x0=read(),x1=read(),a=read(),b=read();
scanf("%s",ss+1); l = strlen(ss+1);
for(ll i=1;i<=l;i++) num[l-i+1] = ss[i] - '0';
num[1] --; for(ll i=1;i<=l;i++) if(num[i] < 0) num[i+1] --,num[i]+=10; if(num[l] <= 0) l--;
// for(ll i=1;i<=l;i++) printf("%d",num[i]); printf("\n");
mod = read();
s.a[1][1] = x1; s.a[1][2] = x0;
p.a[1][1] = a; p.a[2][1] = b; p.a[1][2] = 1; p.a[2][2] = 0;
q = calc(p);
// printf("%lld %lld %lld %lld\n",q.a[1][1],q.a[1][2],q.a[2][1],q.a[2][2]);
return printf("%lld\n",(s*q).a[1][1]),0;
}
C-generator 2
没想到这个年头还有BSGS的题
推一波式子:
然后逆元BSGS就可以了,但是还有点小trick,就是考虑询问不多,我们可以把块的数量分小一点,块的大小分大一点就可以了
其它情况自己判断,注意是到n-1的就行
#include <bits/stdc++.h>
#define mp make_pair
#define pb push_back
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<ll,ll> pii;
const ll mod = 1048575;
inline ll read()
{
ll p=0; ll f=1; char ch=getchar();
while(ch<'0' || ch>'9'){if(ch=='-') f=-1; ch=getchar();}
while(ch>='0' && ch<='9'){p=p*10+ch-'0'; ch=getchar();}
return p*f;
}
ll qpow(ll x,ll k,ll p)
{
ll s = 1;
while(k)
{
if(k&1) s = (s*x) % p;
x = (x*x) % p; k>>=1;
}return s;
}
vector<pii>has[mod + 10];
ll s,block;
ll find(ll x)
{
ll p = x % mod;
for(ll i=0;i<has[p].size();i++) if(has[p][i].fi == x) return has[p][i].se;
return -1;
}
void ins(ll x,ll i)
{
ll p = x % mod; has[p].pb(mp(x,i));
}
void pre(ll a,ll p)
{
// printf("%lld %lld %lld\n",a,x,p);
for(ll i=0;i<mod;i++) has[i].clear();
block = 1000; // printf("%lld\n",b);
s = 1; ll q = (ll)ceil((double)p/block);
for(ll i=0;i<q;i++)
{
if(find(s) == -1) ins(s,i);
s = (s*a) % p;
}
s = qpow(s,p-2,p);
}
ll BSGS(ll x,ll p)
{
ll q = (ll)ceil((double)p/block);
ll s2 = 1; for(ll i=0;i<block;i++)
{
ll nw = find(x*s2%p);
if(nw != -1) return i*q + nw;
s2 = (s2 * s) % p;
}return -1;
}
ll n,x0,a,b,p,q;
int main()
{
ll T = read();
while(T--)
{
n = read(); x0 = read(); a = read(); b = read(); p = read();
q = read();
if(a>1) pre(a,p);
while(q--)
{
ll v = read();
if(a == 0)
{
if(v!=b && v!=x0) printf("-1\n");
else if(v==x0) printf("0\n");
else if(v==b && n>1) printf("1\n");
}
else if(a == 1)
{
if(b == 0 && v!=a) printf("-1\n");
else if(b == 0 && v==a) printf("0\n");
ll ans = (((v-x0)%p+p)%p) * qpow(b , p-2 , p) % p;
printf("%lld\n",(ans < n) ? ans : -1);
}
else
{
ll x = (v * (a-1) + b) % p * qpow((x0 * (a-1) + b) % p , p - 2 , p ) % p;
// printf("%lld\n",x);
ll ans = BSGS(x,p);
printf("%lld\n",(ans < n) ? ans : -1);
}
}
}
return 0;
}
F-maximum clique 1
这个题好像见过?
首先题目就是要求一个一般图最大团,我们可以根据位数的奇偶来分组,发现最多可以形成偶环,所以可以变成二分图
最大团可以变成补图的最大独立集,意思就是把位数差1的连边即可
二分图中最大独立集就可以变成n-最小点覆盖
考虑输出方案,就是要找出是独立集的点,即找出不是最小点覆盖里面的点集
考虑匈牙利二分匹配怎么找到最小点覆盖的点集?
从右边的未匹配点开始,走未匹配边,匹配边,未匹配边。。。。最后走匹配边到右边
把经过的点都标记,左侧的标记点和右侧的未标记点都是最小点覆盖点集里面的点
#include <bits/stdc++.h>
#define pb push_back
using namespace std;
const int N = 5010;
inline int read()
{
int p=0; int f=1; char ch=getchar();
while(ch<'0' || ch>'9'){if(ch=='-') f=-1; ch=getchar();}
while(ch>='0' && ch<='9'){p=p*10+ch-'0'; ch=getchar();}
return p*f;
}
struct node
{
int x,y,nex;
}edge[N*31]; int len,fir[N];
void ins(int x,int y)
{
len++; edge[len].x=x; edge[len].y=y; edge[len].nex = fir[x]; fir[x] = len;
len++; edge[len].y=x; edge[len].x=y; edge[len].nex = fir[y]; fir[y] = len;
}
int n; map<int,bool> mp;
int match[N]; bool chw[N];
bool find(int x)
{
for(int k=fir[x];k!=-1;k=edge[k].nex)
{
int y = edge[k].y;
if(!chw[y])
{
chw[y] = 1;
if(match[y] == 0 || find(match[y]) ){match[y] = x; return 1;}
}
}return 0;
}vector<int> ans;
int a[N],b[N],alen,blen;
bool vis[N],gvis[N];
void dfs(int x)
{
if(vis[x]) return ; vis[x] = 1;
for(int k=fir[x];k!=-1;k=edge[k].nex)
{
int y=edge[k].y;
if(match[y] != x && match[y] && !vis[y]){vis[y] = 1; dfs(match[y]);}
}
}
int main()
{
// freopen("a.out","w",stdout);
len = 0; memset(fir,-1,sizeof(fir));
n = read(); alen = blen = 0; for(int i=1;i<=n;i++)
{
int x = read();
if(__builtin_popcount(x) & 1) a[++alen] = x;
else b[++blen] = x;
}
// for(int i=1;i<=alen;i++) printf("%d ",a[i]); printf("\n");
// for(int i=1;i<=blen;i++) printf("%d ",b[i]); printf("\n");
// printf("%d %d\n",alen,blen);
for(int i=1;i<=alen;i++) for(int j=1;j<=blen;j++) if(__builtin_popcount(a[i]^b[j]) == 1)
{
ins(i,alen+j);
// printf("%d %d\n",i,alen+j);
}
for(int i=1;i<=alen;i++)
{
for(int j=alen+1;j<=n;j++) chw[j] = 0;
find(i);
}
for(int i=alen+1;i<=n;i++) match[match[i]] = i;
// for(int i=1;i<=n;i++) printf("%d ",match[i]); printf("\n");
for(int i=alen+1;i<=n;i++)
{
for(int j=1;j<=n;j++) vis[j] = 0;
if(match[i] == 0) dfs(i);
for(int j=1;j<=n;j++) gvis[j] |= vis[j];
}
for(int i=1;i<=alen;i++) if(!gvis[i]) ans.pb(a[i]);
for(int i=alen+1;i<=n;i++) if(gvis[i]) ans.pb(b[i-alen]);
printf("%d\n",ans.size());
for(int i=0;i<ans.size();i++) printf("%d%c",ans[i]," \n"[i==ans.size()-1]);
return 0;
}
G-subsequence 1
从后往前dp,定义
表示到后面的第几个位,匹配到b串的j位,是大,相等,还是小于的方案数
维护个前缀和,然后有0的情况最后减掉就可以了
#include <bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
using namespace std;
typedef long long ll;
const int N = 3010;
const int mod = 998244353;
inline int read()
{
int p=0; int f=1; char ch=getchar();
while(ch<'0' || ch>'9'){if(ch=='-') f=-1; ch=getchar();}
while(ch>='0' && ch<='9'){p=p*10+ch-'0'; ch=getchar();}
return p*f;
}
char a[N],b[N];
int f[N][N][3],sum[N][N][3];
int main()
{
int t = read();
while(t--)
{
int n = read(); int m = read();
for(int i=1;i<=n;i++) scanf("\n%c",&a[i]);
for(int i=1;i<=m;i++) scanf("\n%c",&b[i]);
// for(int i=1;i<=n;i++) printf("%c",a[i]); printf("\n");
// for(int i=1;i<=m;i++) printf("%c",b[i]); printf("\n");
for(int i=0;i<=n+1;i++) for(int j=0;j<=n+1;j++)
sum[i][j][0] = sum[i][j][1] = sum[i][j][2] = f[i][j][0] = f[i][j][1] = f[i][j][2] = 0;
f[n+1][0][1] = 1; sum[n+1][0][1] = 1;
for(int i=n;i>=1;i--)
{
for(int j=1;j<=n-i+1;j++) for(int k=0;k<3;k++)
{
if(k==0)
{
int x = a[i];
int y = ((m-j+1) > 0) ? b[m-j+1] : 0;
if(x<=y) f[i][j][0] = (f[i][j][0] + sum[i+1][j-1][k]) % mod;
else f[i][j][2] = (f[i][j][2] + sum[i+1][j-1][k]) % mod;
}
else if(k==1)
{
int x = a[i];
int y = ((m-j+1) > 0) ? b[m-j+1] : 0;
if(x<y) f[i][j][0] = (f[i][j][0] + sum[i+1][j-1][k]) % mod;
else if(x==y) f[i][j][1] = (f[i][j][1] + sum[i+1][j-1][k]) % mod;
else f[i][j][2] = (f[i][j][2] + sum[i+1][j-1][k]) % mod;
}
if(k==2)
{
int x = a[i];
int y = ((m-j+1) > 0) ? b[m-j+1] : 0;
if(x<y) f[i][j][0] = (f[i][j][0] + sum[i+1][j-1][k]) % mod;
else f[i][j][2] = (f[i][j][2] + sum[i+1][j-1][k]) % mod;
}
}
for(int j=0;j<=n-i+1;j++) for(int k=0;k<3;k++) sum[i][j][k] = (sum[i+1][j][k] + f[i][j][k]) % mod;
}
int ans = 0;
for(int i=m;i<=n;i++) ans = (ans + sum[1][i][2]) % mod;
for(int i=1;i<=n;i++) if(a[i] == '0')
for(int j=m;j<=n;j++)
// printf("%lld %lld %lld\n",i,j,f[i][j][2]);
ans = (ans + mod - f[i][j][2]) % mod;
printf("%d\n",ans);
}
return 0;
}
H-subsequence 2
就是把每个字母都变成一个点,判断各种恶心的情况,然后拓扑就完事了
#include <bits/stdc++.h>
#define pb push_back
#define rep(i,a,b) for(ll i=(a);i<=(b);i++)
using namespace std;
typedef long long ll;
const int N = 100010;
inline int read()
{
int p=0; int f=1; char ch=getchar();
while(ch<'0' || ch>'9'){if(ch=='-') f=-1; ch=getchar();}
while(ch>='0' && ch<='9'){p=p*10+ch-'0'; ch=getchar();}
return p*f;
}
char ss[N]; int tot = 0;
vector<int> v[11]; int yc[N];
struct node
{
int x,y,nex;
}edge[N*50]; int len,fir[N]; int ru[N];
void ins(int x,int y)
{
len++; edge[len].x=x; edge[len].y=y; ru[y] ++; edge[len].nex = fir[x]; fir[x] = len;
}
queue<int> q; vector<int> ans;
int main()
{
int n = read(); int mm = read(); int m = mm*(mm-1)/2; len = 0; memset(fir,-1,sizeof(fir));
memset(ru,0,sizeof(ru));
while(m--)
{
char a,b;
scanf("\n%c\n%c",&a,&b); int l = read();
for(int i=1;i<=l;i++) scanf("\n%c",&ss[i]);
int x = a-'a'+1; int y = b-'a'+1;
int sumx=0, sumy=0;
for(int i=1;i<=l;i++)
{
if(ss[i] == a) sumx++;
if(ss[i] == b) sumy++;
}
if(v[x].size() != 0 && v[x].size() != sumx){printf("-1\n"); return 0;}
if(v[y].size() != 0 && v[y].size() != sumy){printf("-1\n"); return 0;}
if(v[x].size() == 0) for(int i=1;i<=sumx;i++){tot++; yc[tot] = x; v[x].pb(tot);}
if(v[y].size() == 0) for(int i=1;i<=sumy;i++){tot++; yc[tot] = y; v[y].pb(tot);}
int p1 = -1; int p2 = -1; int last = 0;
for(int i=1;i<=l;i++)
{
if(ss[i] == a){p1++; if(last) ins(last,v[x][p1]); last = v[x][p1];}
if(ss[i] == b){p2++; if(last) ins(last,v[y][p2]); last = v[y][p2];}
}
if(tot > n){printf("-1\n"); return 0;}
}
// printf("!");
if(tot != n){printf("-1\n"); return 0;}
while(!q.empty()) q.pop();
for(int i=1;i<=n;i++) if(ru[i] == 0) q.push(i);
while(!q.empty())
{
int x = q.front(); q.pop(); ans.pb(x);
for(int k=fir[x];k!=-1;k=edge[k].nex)
{
int y = edge[k].y;
ru[y] --; if(ru[y] == 0) q.push(y);
}
}
if(ans.size() != n){printf("-1\n"); return 0;}
else
{
for(int i=0;i<ans.size();i++) printf("%c",'a'+yc[ans[i]]-1);
printf("\n");
}
return 0;
}
I-three points 1
几何题
肯定有一个点在原点,然后一条线段压在下面,并在下边或者右边(上边或者左边的情况只需把长和宽调换一下即可)
另外一个点其实是可以确定的,但是你要判断一下这个点是在这个线段的上面还是下面
然后点的顺序,输出的顺序都要枚举,YY一下就可以了
把长方形的边界放大,不然会卡精度,左右上下边界放大到1e-12可以过
#include <bits/stdc++.h>
#define mp make_pair
#define fi first
#define se second
using namespace std;
typedef pair<long double,long double> pii;
const long double eps = 1e-12;
const long double pi = acos(-1);
inline int read()
{
int p=0; int f=1; char ch=getchar();
while(ch<'0' || ch>'9'){if(ch=='-') f=-1; ch=getchar();}
while(ch>='0' && ch<='9'){p=p*10+ch-'0'; ch=getchar();}
return p*f;
}
pii p1,p2,p3,q1,q2,q3;
long double w,h; bool bk = 0;
long double dis(pii x,pii y){return sqrt((x.fi-y.fi) * (x.fi-y.fi) + (x.se - y.se) * (x.se - y.se));}
void upd(){q1=p1; q2=p2; q3=p3; bk = 1;}
void solve(long double a,long double b,long double c)
{
p1 = mp(0.0,0.0);
long double t1;
if(a <= w) t1 = 0.0 , p2 = mp(a,0);
else t1 = atan(sqrt(a*a-w*w)/w) , p2 = mp(w,sqrt(a*a-w*w));
if(p2.fi > w+eps || p2.fi < -eps || p2.se > h+eps || p2.se < -eps) return ;
long double c2 = (a*a + b*b - c*c) / (2 * a * b);
long double t2 = atan(sqrt(1.0/(c2*c2) - 1.0));
if(t1 + t2 <= pi / 2)
{
long double t3 = t1 + t2;
p3 = mp(cos(t3) * b,sin(t3) * b);
if(p3.fi <= w+eps && p3.se <= h+eps && p3.fi >= -eps && p3.se >= -eps && fabs(dis(p2,p3) - c) <= eps){upd(); return ;}
}
if(t1 - t2 >= 0.0)
{
long double t3 = t1 - t2;
p3 = mp(cos(t3) * b,sin(t3) * b);
if(p3.fi <= w+eps && p3.se <= h+eps && p3.fi >= -eps && p3.se >= -eps && fabs(dis(p2,p3) - c) <= eps){upd(); return ;}
}
}
long double a,b,c;
void check()
{
solve(a,b,c);
solve(a,c,b);
solve(b,a,c);
solve(b,c,a);
solve(c,a,b);
solve(c,b,a);
}
void pr(pii x,pii y,pii z)
{
printf("%.12Lf %.12Lf %.12Lf %.12Lf %.12Lf %.12Lf\n",x.fi,x.se,y.fi,y.se,z.fi,z.se);
}
void output()
{
if(fabs(dis(q1,q2) - a) <= eps && fabs(dis(q1,q3) - b) <= eps && fabs(dis(q2,q3) - c) <= eps){pr(q1,q2,q3); return ;}
if(fabs(dis(q1,q3) - a) <= eps && fabs(dis(q1,q2) - b) <= eps && fabs(dis(q2,q3) - c) <= eps){pr(q1,q3,q2); return ;}
if(fabs(dis(q2,q1) - a) <= eps && fabs(dis(q2,q3) - b) <= eps && fabs(dis(q1,q3) - c) <= eps){pr(q2,q1,q3); return ;}
if(fabs(dis(q2,q3) - a) <= eps && fabs(dis(q2,q1) - b) <= eps && fabs(dis(q1,q3) - c) <= eps){pr(q2,q3,q1); return ;}
if(fabs(dis(q3,q1) - a) <= eps && fabs(dis(q3,q2) - b) <= eps && fabs(dis(q1,q2) - c) <= eps){pr(q3,q1,q2); return ;}
if(fabs(dis(q3,q2) - a) <= eps && fabs(dis(q3,q1) - b) <= eps && fabs(dis(q1,q2) - c) <= eps){pr(q3,q2,q1); return ;}
}
int main()
{
int T = read();
while(T--)
{
bk = 0; w = read(); h = read(); a = read(); b = read(); c = read();
check();
if(bk){output(); continue;}
swap(w,h);
check();
swap(q1.fi,q1.se); swap(q2.fi,q2.se); swap(q3.fi,q3.se);
if(bk){output(); continue;}
}
return 0;
}