CSP 2019 RP++
读入:(转自:chuyds's Blog
法一:
while(scanf("%d",&a)!=EOF)
法二:
while(cin>>n)
法三:
while(~scanf("%d",&a))
1.最小生成树
只会Kruskal w
#include<bits/stdc++.h>
using namespace std;
inline int read(){
int ans=0;
char last=' ',ch=getchar();
while(ch>'9'||ch<'0') last=ch,ch=getchar();
while(ch>='0'&&ch<='9') ans=(ans<<1)+(ans<<3)+ch-'0',ch=getchar();
if(last=='-') ans=-ans;
return ans;
}
int n,m;
int fa[5010];
struct node{
int u,v,w;
}e[200010];
bool cmp(node a,node b) {
return a.w<b.w;
}
int find(int x){
if(fa[x]!=x) fa[x]=find(fa[x]);
return fa[x];
}
int main(){
n=read();
m=read();
for(int i=1;i<=m;i++) {
e[i].u=read();
e[i].v=read();
e[i].w=read();
}
sort(e+1,e+m+1,cmp);
int ans=0;
for(int i=1;i<=n;i++) fa[i]=i;
for(int i=1,u,v,fu,fv;i<=m;i++) {
u=e[i].u;
v=e[i].v;
fu=find(u);
fv=find(v);
if(fu==fv) continue;
fa[fu]=fv;
ans+=e[i].w;
}
printf("%d",ans);
return 0;
}
2.单源最短路
#include<bits/stdc++.h>
#define pa pair<int,int>
using namespace std;
inline int read(){
int ans=0;
char last=' ',ch=getchar();
while(ch>'9'||ch<'0') last=ch,ch=getchar();
while(ch>='0'&&ch<='9') ans=(ans<<1)+(ans<<3)+ch-'0',ch=getchar();
if(last=='-') ans=-ans;
return ans;
}
const int mxn=100010;
int n,m,s;
int head[mxn],ecnt;
struct node {
int to,dis,nxt;
}e[mxn<<1];
void add(int from,int to,int dis){
++ecnt;
e[ecnt].nxt=head[from];
e[ecnt].to=to;
e[ecnt].dis=dis;
head[from]=ecnt;
}
int dis[mxn];
bool vis[mxn];
priority_queue<pa,vector<pa>,greater<pa> > q;
void dij(int s){
dis[s]=0;
q.push(make_pair(dis[s],s));
while(!q.empty()){
int u=q.top().second;
q.pop();
if(vis[u]) continue;
vis[u]=1;
for(int i=head[u],v;i;i=e[i].nxt){
v=e[i].to;
if(dis[v]>dis[u]+e[i].dis){
dis[v]=dis[u]+e[i].dis;
q.push(make_pair(dis[v],v));
}
}
}
}
int main(){
n=read();
m=read();
s=read();
memset(dis,0x3f,sizeof(dis));
for(int i=1,u,v,w;i<=m;i++){
u=read();
v=read();
w=read();
add(u,v,w);
}
dij(s);
for(int i=1;i<=n;i++) printf("%d ",dis[i]);
return 0;
}
#include<bits/stdc++.h>
using namespace std;
inline int read(){
int ans=0;
char last=' ',ch=getchar();
while(ch>'9'||ch<'0') last=ch,ch=getchar();
while(ch>='0'&&ch<='9') ans=(ans<<1)+(ans<<3)+ch-'0',ch=getchar();
if(last=='-') ans=-ans;
return ans;
}
const int mxn=100010;
int n,m,s;
int head[mxn],ecnt;
struct node {
int to,dis,nxt;
}e[mxn<<3];
void add(int from,int to,int dis){
++ecnt;
e[ecnt].nxt=head[from];
e[ecnt].to=to;
e[ecnt].dis=dis;
head[from]=ecnt;
}
int dis[mxn];
bool vis[mxn];
queue<int> Q;
void spfa(){
Q.push(s);
for(int i=1;i<=n;i++) dis[i]=2147483647,vis[i]=0;
vis[s]=1;dis[s]=0;
while(!Q.empty()) {
int u=Q.front();
Q.pop();
vis[u]=0;
for(int i=head[u],v;i;i=e[i].nxt) {
v=e[i].to;
if(dis[v]>dis[u]+e[i].dis) {
dis[v]=dis[u]+e[i].dis;
if(!vis[v]) Q.push(v),vis[v]=1;
}
}
}
}
int main(){
n=read();
m=read();
s=read();
for(int i=1,u,v,w;i<=m;i++){
u=read();
v=read();
w=read();
add(u,v,w);
}
spfa();
for(int i=1;i<=n;i++) printf("%d ",dis[i]);
return 0;
}
3.tarjan
void tarjan(int u) {
dfn[u]=low[u]=++tim;
vis[u]=1;
s[top++]=u;
for(int i=head[u],v;i;i=e[i].nxt) {
v=e[i].to;
if(!dfn[v]) {
tarjan(v);
low[u]=min(low[v],low[u]);
} else
if(vis[v])
low[u]=min(dfn[v],low[u]);
}
if(dfn[u]==low[u]){
++scc_cnt;
while(s[top]!=u){
top--;
vis[s[top]]=0;
scc[s[top]]=scc_cnt;
cnt[scc_cnt]++;
}
}
}
4.kmp
#include<bits/stdc++.h>
using namespace std;
char a[mxn],b[mxn];
int lena,lenb;
int p[mxn];
void ych(){
p[1]=0;
int j=0;
for(int i=1;i<lenb;i++) {
while(j>0&&b[j+1]!=b[i+1]) j=p[j];
if(b[j+1]==b[i+1]) j++;
p[i+1]=j;
}
}
void kmp(){
int j=0;
for(int i=0;i<lena;i++) {
while(j>0&&b[j+1]!=a[i+1]) j=p[j];
if(b[j+1]==a[i+1]) j++;
if(j==lenb) {
printf("%d\n",i+1-lenb+1);
j=p[j];
}
}
}
int main(){
scanf("%s%s",a+1,b+1);
lena=strlen(a+1);
lenb=strlen(b+1);
ych();
kmp();
return 0;
}
trie树:
#include<bits/stdc++.h>
using namespace std;
int n,m,tot=1;
char word[55];
int trie[500011][27];
int vis[500011];
void insert(char *s,int rt) {
for(int i=0;i<strlen(s);i++) {
int x=s[i]-'0';
if(trie[rt][x]==0) trie[rt][x]=++tot;
rt=trie[rt][x];
}
vis[rt]=1;
}
int search(char *s,int rt) {
for(int i=0;i<strlen(s);i++) {
int x=s[i]-'0';
if(trie[rt][x]==0) return 0;
rt=trie[rt][x];
}
if(vis[rt]==0) return 0;
if(vis[rt]==1) {
vis[rt]=2;
return 1;
}
if(vis[rt]==2)
return 2;
}
int main() {
scanf("%d",&n);
for(int i=1;i<=n;i++) {
scanf("%s",word);
insert(word,1);
}
scanf("%d",&m);
for(int i=1;i<=m;i++) {
scanf("%s",word);
int k=search(word,1);
if(!k) printf("WRONG\n");
else {
if(k==1)
printf("OK\n");
else
printf("REPEAT\n");
}
}
return 0;
}
5.线性筛
#include<bits/stdc++.h>
using namespace std;
const int mxn=100010;
int n;
bool is[mxn];
int pri[mxn],cnt;
int main(){
scanf("%d",&n);
for(int i=2;i<=n;i++) {
if(!is[i]) pri[++cnt]=i;
for(int j=1;j<=cnt&&pri[j]*i<=n;j++) {
is[i*pri[j]]=1;
if(i%pri[j]==0) break;
}
}
for(int i=1;i<=cnt;i++) cout<<pri[i]<<" ";
return 0;
}
6.求解同余方程:
ax=by+c\\
即求解ax+by=c(正负无所谓\\
若方程有解,则:\\
c=k\times gcd(a,b) \ \ k\in N^*\\
扩展欧几里得定理求得的解为ax+by=exgcd(a,b)\\
若要求解ax+by=k\times exgcd(a,b)\\在求解ax+by=exgcd(a,b)基础上,同乘k
\\x,y的通解:
x+=b/gcd(a,b),y-=a/gcd(a,b)
\]
void exgcd(int a,int b,int &x,int &y) {
if(b==0) {x=1;y=0;return a;}
int g=exgcd(b,a%b,x,y);
int t=x;
x=y;
y=t-a/b*x;
return g;
}
7.中国剩余定理:
若\(a_1,a_2 \cdots\cdots a_n\)是两两互质的正整数,\(M= \prod_{i=1}^na_i,M_i=M/a_i\),\(t_i\)是线性同余方程\(M_it_i≡1(\mod a_i)\)的一个解。对于任意的n个整数\(b_1,b_2 \cdots \cdots b_n\),则同余方程组:
x\equiv b_1 (\mod a_1)\\
x\equiv b_2 (\mod a_2)\\
x\equiv b_3 (\mod a_3)\\
……\\
x\equiv b_n (\mod a_n)\\
\end{cases}
\]
有整数解,方程组的解为\(x=b_1M_1t_1+b_2M_2t_2+ \cdots \cdots +b_nM_nt_n\).并且在%M意义下有唯一解
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n;
ll M,x,y,ans;
ll a[15],b[15];
ll exgcd(ll a,ll b,ll &x,ll &y) {
if(b==0) {x=1;y=0;return a;};
ll g=exgcd(b,a%b,x,y);
ll t=x;
x=y;
y=t-a/b*x;
return g;
}
void solve(int k) {
ll M_=M/a[k];
exgcd(M_,a[k],x,y);
ans=(ans+((x*M_)%M*b[k])%M+M)%M;
}
int main() {
scanf("%d",&n);
M=1;
for(int i=1;i<=n;i++)
scanf("%lld%lld",&a[i],&b[i]),M*=a[i];
for(int i=1;i<=n;i++)
solve(i);
printf("%lld",ans);
return 0;
}
8.树状数组:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll n,m;
ll c[1000000];
ll lowbit(ll x) { return x&(-x);}
void add(ll x,ll ad) {
while(x<=n) {
c[x]+=ad;
x+=lowbit(x);
}
}
ll sum(ll x) {
ll S=0;
while(x>0) {
S+=c[x];
x-=lowbit(x);
}
return S;
}
int main() {
scanf("%lld%lld",&n,&m);
for(int i=1,a;i<=n;i++) {
scanf("%d",&a);
add(i,a);
}
for(int i=1,opt,x,y;i<=m;i++) {
scanf("%d%d%d",&opt,&x,&y);
if(opt==1)
add(x,y);
else
printf("%lld\n",sum(y)-sum(x-1));
}
return 0;
}
9.线段树:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int mxn=100010;
int n,m;
ll a[mxn];
ll t[mxn<<2],tag[mxn<<2];
void build(int k,int l,int r) {
if(l==r) {
t[k]=a[l];
return;
}
int mid=(l+r)>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
t[k]=t[k<<1]+t[k<<1|1];
}
void pushdown(int k,int l,int r) {
int mid=(l+r)>>1;
if(!tag[k]) return;
tag[k<<1]+=tag[k];
tag[k<<1|1]+=tag[k];
t[k<<1]+=(mid-l+1)*tag[k];
t[k<<1|1]+=(r-mid)*tag[k];
tag[k]=0;
}
void modify(int k,int l,int r,int x,int y,int q) {
if(x<=l&&r<=y) {
tag[k]+=q;
t[k]+=(r-l+1)*q;
return;
}
pushdown(k,l,r);
int mid=(l+r)>>1;
if(x<=mid) modify(k<<1,l,mid,x,y,q);
if(y>mid) modify(k<<1|1,mid+1,r,x,y,q);
t[k]=t[k<<1]+t[k<<1|1];
}
ll query(int k,int l,int r,int x,int y) {
if(x<=l&&r<=y)
return t[k];
pushdown(k,l,r);
int mid=(l+r)>>1;
ll rtn=0;
if(x<=mid) rtn+=query(k<<1,l,mid,x,y);
if(y>mid) rtn+=query(k<<1|1,mid+1,r,x,y);
return rtn;
}
int main() {
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
build(1,1,n);
for(int i=1,opt,x,y,k;i<=m;i++) {
scanf("%d%d%d",&opt,&x,&y);
if(opt==1) {
scanf("%d",&k);
modify(1,1,n,x,y,k);
}
else
printf("%lld\n",query(1,1,n,x,y));
}
}
10.LCA:
(树剖
#include<bits/stdc++.h>
using namespace std;
const int mxn=500010;
int n,m,S;
struct node {
int to,nxt;
}e[mxn<<1];
int ecnt,head[mxn];
void add(int from,int to) {
++ecnt;
e[ecnt].to=to;
e[ecnt].nxt=head[from];
head[from]=ecnt;
}
int fa[mxn],siz[mxn],dep[mxn],son[mxn];
void dfs1(int u,int f) {
fa[u]=f;
siz[u]=1;
dep[u]=dep[f]+1;
int maxn=-1;
for(int i=head[u],v;i;i=e[i].nxt) {
v=e[i].to;
if(v==f) continue;
dfs1(v,u);
siz[u]+=siz[v];
if(siz[v]>maxn) {
maxn=siz[v];
son[u]=v;
}
}
}
int top[mxn];
void dfs2(int u,int f) {
if(son[f]==u) top[u]=top[f];
else top[u]=u;
if(son[u]) dfs2(son[u],u);
for(int i=head[u],v;i;i=e[i].nxt) {
v=e[i].to;
if(v==f||v==son[u]) continue;
dfs2(v,u);
}
}
int getlca(int x,int y) {
while(top[x]!=top[y]) {
if(dep[top[x]]>dep[top[y]])
x=fa[top[x]];
else
y=fa[top[y]];
}
if(dep[x]>dep[y]) return y;
else return x;
}
int main() {
scanf("%d%d%d",&n,&m,&S);
for(int i=1,x,y;i<n;i++) {
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
}
dfs1(S,0);
dfs2(S,0);
for(int i=1,a,b,lca;i<=m;i++) {
scanf("%d%d",&a,&b);
lca=getlca(a,b);
printf("%d\n",lca);
}
return 0;
}
倍增:
#include<bits/stdc++.h>
using namespace std;
const int mxn=500010;
int n,m,S;
struct node {
int to,nxt;
}e[mxn<<1];
int ecnt,head[mxn];
void add(int from,int to) {
++ecnt;
e[ecnt].to=to;
e[ecnt].nxt=head[from];
head[from]=ecnt;
}
int fa[mxn][20],dep[mxn];
void dfs(int u,int f) {
fa[u][0]=f;
for(int i=1;i<=19;i++)
fa[u][i]=fa[fa[u][i-1]][i-1];
dep[u]=dep[f]+1;
for(int i=head[u],v;i;i=e[i].nxt) {
v=e[i].to;
if(v==f) continue;
dfs(v,u);
}
}
int getlca(int x,int y) {
if(dep[x]>dep[y]) swap(x,y);
for(int i=19;i>=0;i--)
if(dep[fa[y][i]]>=dep[x])
y=fa[y][i];
if(x==y) return x;
for(int i=19;i>=0;i--) {
if(fa[x][i]!=fa[y][i]) {
x=fa[x][i];
y=fa[y][i];
}
}
return fa[x][0];
}
int main() {
scanf("%d%d%d",&n,&m,&S);
for(int i=1,x,y;i<n;i++) {
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
}
dfs(S,0);
for(int i=1,x,y,lca;i<=m;i++) {
scanf("%d%d",&x,&y);
lca=getlca(x,y);
printf("%d\n",lca);
}
return 0;
}
12.堆:
#include<bits/stdc++.h>
#define pa pair<int,int>
#define mk make_pair
using namespace std;
inline int read() {
int ans=0;
char last=' ',ch=getchar();
while(ch>'9'||ch<'0') last=ch,ch=getchar();
while(ch>='0'&&ch<='9') ans=(ans<<1)+(ans<<3)+ch-'0',ch=getchar();
if(last=='-') ans=-ans;
return ans;
}
int n,siz;
int heap[1000080];
void insert(int x) {
heap[++siz]=x;
int nxt,now=siz;
while(now>1) {
nxt=now>>1;
if(heap[nxt]<=heap[now]) break;
swap(heap[now],heap[nxt]);
now=nxt;
}
}
void Delete() {
heap[1]=heap[siz--];
int now=1,nxt;
while((now<<1)<=siz) {
nxt=now<<1;
if(nxt<siz&&heap[nxt+1]<heap[nxt]) nxt++;
if(heap[now]<=heap[nxt]) break;
swap(heap[now],heap[nxt]);
now=nxt;
}
}
int main() {
n=read();
for(int i=1,opt,x;i<=n;i++) {
opt=read();
if(opt==1) {
x=read();
insert(x);
}
if(opt==2)
printf("%d\n",heap[1]);
if(opt==3)
Delete();
}
return 0;
}
13.逆元:
定义:
若\(ax\equiv 1(\mod b)\),且a与b互质,那么我们就能定义: x为a的逆元,记为\(a^{-1}\),所以我们也可以称 x 为 a 在 \(\mod b\) 意义下的倒数,
1.扩展欧几里得算法:
由逆元定义可知,求a在mod b意义下的逆元,就是求ax+by=1的解,因此我们可以使用扩欧算法:
int exgcd(int a,int b,int &x,int &y) {
if(b==0){x=1;y=0;return a;}
int g=exgcd(b,a%b,x,y);
int t=x;
x=y;
y=t-a/b*x;
}
2.利用费马小定理或者欧拉定理
费马小定理:
如果 a,p 互质,那么 \(a^{p-1} ≡ 1 \ \ (mod \ p)\)
由此可以推出,\(a^{-1}=a^{p-2}\)
那么我们就可以用快速幂来完成求逆元的任务;
欧拉定理:
如果a,p互质,那么\(a^{\phi(p)} ≡ 1 \;(mod\; p)\),当 p 为质数时,\(\phi(p)=p-1\)。
(只顺手写个快速幂行吧?)
ll quick_pow(int x,int k) {
ll ans=1;
while(k){
if(k&1) ans=(ans*x)%mod;
x=(x*x)%mod;
}
return ans;
}
3.线性递推(用于求解一段数的逆元
则有:ki+r\equiv 0(mod \ p)①\\
①式左右同乘i^{-1}\times r^{-1}得:\\
kr^{-1}+i^{-1}\equiv 0(mod \ p)\\
移项得:i^{-1} \equiv -k*r^{-1} (mod\ p) \\
带入 k=\left\lfloor\dfrac{p}{i}\right\rfloor,r=p\%i\\
i^{-1}\equiv -\left\lfloor\dfrac{p}{i}\right\rfloor*(p\mod i)^{-1}(mod\ p)\\
由于(p\mod i)<i\\
因此在求出i^{-1}之前,我们已经求出(p\mod i)^{-1}\\
用inv数组记录逆元
则:inv[i]=-\left\lfloor\dfrac{p}{i}\right\rfloor*inv[p\mod i] \mod p\\
为了保证逆元>0,所以要在右边+p,即:inv[i]=-\left\lfloor\dfrac{p}{i}\right\rfloor*inv[p\mod i]+p \mod p\\
inv[1]=1;inv[0]=tan\frac{π}{2}设为0
\]
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n,p;
ll inv[3000010];
int main() {
scanf("%d%d",&n,&p);
inv[1]=1;
puts("1");
for(int i=2;i<=n;i++) {
inv[i]=((-(p/i)*inv[p%i]+p)%p+p)%p;
printf("%lld\n",inv[i]);
}
return 0;
}
14.矩阵加速:(模板
a[x]=a[x-1]+a[x-3] (a>3)
\]
转移矩阵:
\]
15.高精度:
#include<bits/stdc++.h>
using namespace std;
char A[10090],B[10090];
int a[10090],b[10090],c[10090];
void sum() {
scanf("%s",A);
int lena=strlen(A);
for(int i=0;i<lena;i++)
a[lena-i]=A[i]-'0';
scanf("%s",B);
int lenb=strlen(B);
for(int i=0;i<lenb;i++)
b[lenb-i]=B[i]-'0';
int len=max(lena,lenb);
for(int i=1;i<=len;i++) {
c[i]=a[i]+b[i];
}
for(int i=1;i<=len;i++) {
c[i+1]+=(c[i]/10);
c[i]%=10;
}
if(c[len+1]!=0) len++;
for(int i=len;i>=1;i--)
printf("%d",c[i]);
}
void jian(){
int bj=1;
scanf("%s",A);
scanf("%s",B);
int lena=strlen(A);
int lenb=strlen(B);
if(lena<lenb) {
bj=-1;
swap(A,B);
swap(lena,lenb);
}
if(lena==lenb&&strcmp(A,B)<0) {
bj=-1;
swap(A,B);
swap(lena,lenb);
}
for(int i=0;i<lena;i++)
a[lena-i]=A[i]-'0';
for(int i=0;i<lenb;i++)
b[lenb-i]=B[i]-'0';
int len=max(lena,lenb);
for(int i=1;i<=len;i++)
c[i]=a[i]-b[i];
for(int i=1;i<=len;i++) {
if(c[i]<0) {
c[i]+=10;
c[i+1]--;
}
}
if(bj==-1) printf("-");
while(c[len]==0&&len>1) len--;
for(int i=len;i>=1;i--)
printf("%d",c[i]);
}
void Mul() {
scanf("%s",A);
int lena=strlen(A);
for(int i=0;i<lena;i++)
a[lena-i]=A[i]-'0';
scanf("%s",B);
int lenb=strlen(B);
for(int i=0;i<lenb;i++)
b[lenb-i]=B[i]-'0';
for(int i=1;i<=lena;i++)
for(int j=1;j<=lenb;j++)
c[i+j-1]+=a[i]*b[j];
for(int i=1;i<=lena+lenb-1;i++) {
c[i+1]+=(c[i]/10);
c[i]%=10;
}
int len=lena+lenb-1;
while(c[len+1]>0) {
c[len+2]+=(c[len+1]/10);
c[len+1]%=10;
len++;
}
for(int i=len;i>=1;i--)
printf("%d",c[i]);
}
int main() {
scanf("%s",A);
int lena=strlen(A);
for(int i=0;i<lena;i++)
a[lena-i]=A[i]-'0';
int B;
scanf("%d",&B);
for(int i=lena;i>=1;i--) {
c[i]=a[i]/B;
a[i-1]+=(a[i]%B)*10;
}
while(c[lena]==0&&lena>0) lena--;
for(int i=lena;i>=1;i--)
printf("%d",c[i]);
return 0;
}
16.ST表:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int inf=2147483647;
inline ll read()
{
char ch=getchar();
ll x=0;
bool f=0;
while(ch<'0'||ch>'9')
{
if(ch=='-') f=1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=(x<<3)+(x<<1)+(ch^48);
ch=getchar();
}
return f?-x:x;
}
int n,m,a[1000009],st[1000009][23];
int lg[100009];
int qry(int l,int r)
{
int qwq=log((double)(r-l+1))/log(2.0);
return max(st[l][qwq],st[r-(1<<qwq)+1][qwq]);
}
int main()
{
n=read();m=read();
for(int i=1;i<=n;i++)
{
a[i]=read();
st[i][0]=a[i];
}
for(int i=1;(1<<i)<=n;i++)
{
for(int j=1;j<=n;j++)
{
st[j][i]=max(st[j][i-1],st[j+(1<<(i-1))][i-1]);
}
}
while(m--)
{
int l=read(),r=read();
printf("%d\n",qry(l,r));
}
}
17.高斯消元:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> pr;
const double pi=acos(-1);
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define Rep(i,u) for(int i=head[u];i;i=Next[i])
#define clr(a) memset(a,0,sizeof a)
#define pb push_back
#define mp make_pair
#define fi first
#define sc second
ld eps=1e-9;
ll pp=1000000007;
ll mo(ll a,ll pp){if(a>=0 && a<pp)return a;a%=pp;if(a<0)a+=pp;return a;}
ll powmod(ll a,ll b,ll pp){ll ans=1;for(;b;b>>=1,a=mo(a*a,pp))if(b&1)ans=mo(ans*a,pp);return ans;}
ll read(){
ll ans=0;
char last=' ',ch=getchar();
while(ch<'0' || ch>'9')last=ch,ch=getchar();
while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
if(last=='-')ans=-ans;
return ans;
}
//head(lh的代码头)
int n,m;
double a[100][100];
bool check(int k){
if(fabs(a[k][n+1])<eps)return 1;// 如果小于0,返回1
for(int i=1;i<=n;i++)
if(fabs(a[k][i])>eps)return 1;//第k行的每个数都大于0
return 0;
}
int main(){
n=read();m=read();//m*n的矩阵,
// a_i,1 a_i,2 ... a_i,n a_i,n+1
for(int i=1;i<=m;i++)
for(int j=1;j<=n+1;j++)a[i][j]=read();//输入矩阵元素(因为除了这个m*n的矩阵,还要有一行答案qwq) (看洛谷题吧qwq)
for(int j=1;j<=m;j++){
for(int k=1;k<=n+1;k++)cout<<a[j][k]<<" ";
puts("");
}//先把矩阵输出辽一遍
int flag=0;
for(int i=1;i<=n;i++){
int t=i;
while(a[t][i]==0 && t<=n)t+=1;
if(t==n+1){
flag=1;
continue;
}//if判断是否有一行全为0,如果全为0 那么我们就少了至少1个方程,那么这个方程显然无唯一解
for(int j=1;j<=n+1;j++)swap(a[i][j],a[t][j]);//交换第i行和第t行的值,目的在于交换第i行和第t行后可以使a[1][1]!=0
double kk=a[i][i];//找到对角线qwq
for(int j=1;j<=n+1;j++)a[i][j]/=kk;//把这一行的每一项都除以对角线,使得对角线为1
for(int j=1;j<=m;j++) //这里真的要详细地讲一讲咯
if(i!=j){//首先i!=j这样就不再消对角线上的数了
double kk=a[j][i];//定义kk为第j行第i列的数
for(int k=1;k<=n+1;k++)//把每一项消成0qwq(先把第一列除了对角线全消为0然后第二第三……)
// 关于处理对角线这里以i=1,j=3做例子:当k=3时,a[3][3]-=a[3][1]*a[1][3]而这个时候a[3][1]已经为0,故对对角线无影响
a[j][k]-=kk*a[i][k];
}
puts("------------");//画一个杠杠来分割每一次消元结果
for(int j=1;j<=m;j++){
for(int k=1;k<=n+1;k++)cout<<a[j][k]<<" ";//输出每次消元结果
puts("");//输出空格
}
}
if(flag){//判断无解和多解的情况(上面已经提到了) 已经懵bi求救qwq
for(int i=1;i<=m;i++)
if(!check(i)){//利用check判断是无解还是多解
printf("No solution\n");
return 0;
}
//每个答案行如果有一个等于0的数就多解??
printf("So many solutions\n");
}
}
-------------------------
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
using namespace std;
long long read(){
long long ans=0;
char last=' ',ch=getchar();
while(ch<'0' || ch>'9')last=ch,ch=getchar();
while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
if(last=='-')ans=-ans;
return ans;
}
int n,m;
double a[100][100];
int main(){
n=read();
for(int i=1;i<=n;i++)
for(int j=1;j<=n+1;j++)a[i][j]=read();
int flag=0;
for(int i=1;i<=n;i++){
int t=i;
while(a[t][i]==0 && t<=n)t+=1;
if(t==n+1){
flag=1;
continue;
}
for(int j=1;j<=n+1;j++)swap(a[i][j],a[t][j]);
double kk=a[i][i];
for(int j=1;j<=n+1;j++)a[i][j]/=kk;
for(int j=1;j<=n;j++)
if(i!=j){
double kk=a[j][i];
for(int k=1;k<=n+1;k++)
a[j][k]-=kk*a[i][k];
}
}
if(flag)printf("No Solution\n");
else {for(int i=1;i<=n;i++)
printf("%.2lf\n",a[i][n+1]);}
return 0;
}
//和上面代码差不多的,只不过这个输出的是第n+1行,也就是每一个未知数的解(因为都消成1了qwq)
18.矩阵求逆:
#include<cstdio>
#include<iostream>
using namespace std;
typedef long long LL;
const int N=405;
int mod;
int n,m;
LL f[N][N<<1];//与下文相照应,这里N<<1指N/2,为了构造单位矩阵而乘的2
LL r,ret;
LL ksm(LL u,LL v){
ret=1;
while(v){
if(v&1)ret=ret*u%mod;
u=u*u%mod;v>>=1;
}
return ret;
}
int main(){
scanf("%d%d",&n,&mod);
m=n*2; //乘2是为了后面建立一个单位矩阵
for(int i=1;i<=n;++i){
for(int j=1;j<=n;j++)
scanf("%lld",&f[i][j]);//输入n*n的矩阵
f[i][n+i]=1; //在 f后面又搞了一个单位矩阵qwq
}
for(int i=1;i<=n;++i){ //高斯消元的板子
for(int j=i;j<=n;j++)
if(f[j][i]){
for(int k=1;k<=m;k++)
swap(f[i][k],f[j][k]);
break;
}
if(!f[i][i]){
puts("No Solution");
return 0;
} //判断是否有解(对角线为0)
r=ksm(f[i][i],mod-2);
for(int j=i;j<=m;++j)
f[i][j]=f[i][j]*r%mod;
for(int j=1;j<=n;++j)
if(j!=i){
r=f[j][i];
for(int k=i;k<=m;++k)
f[j][k]=(f[j][k]-r*f[i][k]%mod+mod)%mod;
}
}
for(int i=1;i<=n;++i,puts(""))
for(int j=n+1;j<=m;++j)
printf("%lld ",f[i][j]);
return 0;
}
CSP 2019 RP++的更多相关文章
- NOIP 2019 RP++
\[\huge NOIP^{2019}_{RP++}\] \[\huge NOIP^{2019}_{Score++}\]
- CSP 2019游记 & 退役记
扶苏让我记录他AK CSP 的事实 ZAY NB!!! "你不配" 两年半的旅行结束了,我背着满满的行囊下了车,望着毫不犹豫远去的列车,我笑着哭了,笑着翻着我的行囊-- 游记 Da ...
- CSP 2019 游记
Day -32 开坑. 没什么好说的,等个 5 天等初赛(应该叫第一轮认证)挂掉之后就能弃坑了. 今天开始停课,虽然每天只停半天,但是感觉还是特别的舒服~ 然而得等初赛过了才能全天停课-- 没关系,熬 ...
- CSP 2019 退役记
声明:博主不会时空穿越,也没有造成恐慌,不应禁赛三年 Day0 上午:打板子 Polya定理; exkmp; exbsgs; 乘法逆元; 矩阵快速幂; 扫描线; ST表; excrt; Dirichl ...
- CSP 2019 模板整合
qwq以下都为9.24后写的模板 namespace IO{ const int S = 1 << 20; char I[S + 1], *Is = I, *It = I, O[S + 1 ...
- 括号树 noip(csp??) 2019 洛谷 P5658
洛谷AC通道 本题,题目长,但是实际想起来十分简单. 首先,对于树上的每一个后括号,我们很容易知道,他的贡献值等于上一个后括号的贡献值 + 1.(当然,前提是要有人跟他匹配,毕竟题目中要求了,是不同的 ...
- Diary -「CSP 2019 J/S」 游记
\(\text{Day 0}\) 试机, 总体感觉不错, 至少不像初一时候的紧张, 毕竟是中青年选手了 ( ? ) 当晚睡得挺好, 虽然是冲着一等奖去的, 但还是没有给自己过多的思想包 ...
- 洛谷 题解 P5595 【【XR-4】歌唱比赛】
本蒟蒻又双叒叕被爆踩了. 考试时一遍过 其实这题还是很简单的,难度不会大于普及组T1. CSP 2019 RP++ 看开始看到题目,觉得特别长,不想看... 我来和你们分析分析题目,你们就都可以秒了. ...
- N(C)O(S)I(P)P 2019 退役记
N(C)O(S)I(P)P 2019 退役记 day-4 今天下午老师突然咕了,于是一下午欢乐时光 今天上午考试T3线段树维护个区间加,区间乘 一遍过编译,一遍过样例(第一次,俺比较弱(虽然也发现和暴 ...
随机推荐
- 阿里云运行docker容器报错
[root@izbp145axkc98giot5b448z ~]# docker run -d 231d40e811cd -p 80:80 --name=nginx 56896ff0b49cfe5f1 ...
- JavaWeb_(Hibernate框架)Hibernate中对象的三种状态
对象的三种状态 瞬时状态: 实体 没有id.没有与session关联 持久化状态: 特点:持久化状态对象的任何改变都会同步到数据库中 游离态[也称作托管态]: 实体 有id,没有与session关联 ...
- TCP 之 FIN_WAIT_2状态处理流程
概述 在主动关闭方发送了FIN之后,进入FIN_WAIT_1状态,在此状态收到了ACK,则进入FIN_WAIT_2状态,而FIN_WAIT_2后续要做的工作是等待接收对端发过来的FIN包,并且发送AC ...
- koa 基础(十八)es6中的类、静态方法、继承
1.app.js /** * es6中的类.静态方法.继承 */ // 定义Person类 class Person { constructor(name, age) { /*类的构造函数,实例化的时 ...
- leetcode131分割回文串
class Solution { public: vector<vector<string>> ans; bool isok(string s){ ; ; while(i< ...
- postman提交数组格式方式
提交数组格式数据,对应的服务器端接收的是@RequestBody 和对应的接收值
- 关于 About
关于我 我是 Ivy,目前武汉大学 GIS 专业在读硕士研究生,业余渣程序媛. 写了一些不起眼的代码(参看我的 GitHub),做了一些不起眼的小研究(参看我的 ResearchGate). 关于本站 ...
- (“(null)” is of a model that is not supported by this version of Xcode. Please...)
真机测试遇到以下问题: (还以为手机不支持Xcode的版本呢) 解决方法: 发现只要将XCode重启后就可以真机运行了,碰见这个问题的朋友可以试下,我反正是被坑了半小时...
- springboot子模块 @Autowired无法找到其他模块的接口和类的解决方法
在main的启动类上添加 @SpringBootApplication(scanBasePackages = {"com.shangsheng"})或者@ComponentScan ...
- JavaScript基础入门06
目录 JavaScript 基础入门06 Math 对象 Math对象的静态属性 Math对象的静态方法 指定范围的随机数 返回随机字符 三角函数 Date对象 基础知识 日期对象具体API 构造函数 ...