题目链接:Codeforces Round #686 (Div. 3)
A. Special Permutation
整体向后循环移一位
int main()
{
int t;
cin >> t;
while(t--)
{
int n;
cin >> n;
for(int i=1;i<=n;i++)
{
if((i+1)%(n+1)==0) cout << 1 << ' ';
else
cout << (i+1)%(n+1) << ' ';
}
cout << endl;
}
}
B. Unique Bid Auction
按题意模拟即可
int a[maxn],book[maxn];
int main()
{
int t;
cin >> t;
while(t--)
{
memset(book,0,sizeof(book));
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
book[a[i]]++;
}
int pos=-1,minn=inf;
for(int i=1;i<=n;i++)
{
if(book[a[i]]==1 && a[i]<minn)
{
minn=a[i];
pos=i;
}
}
printf("%d\n",pos);
}
}
C. Sequence Transformation
#include<cmath>
#include<iostream>
#include<sstream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<istream>
#include<vector>
#include<stack>
#include<set>
//#include<unordered_map>
#include<map>
#include<algorithm>
#include<queue>
#define mmp make_pair
#define inf 0x3f3f3f3f
#define llinf 0x7fffffffffffffff
using namespace std;
typedef long long ll;
typedef pair<int,int> PP;
typedef double ld;
struct A {
int num,bz;
}a[200010];
bool cmp(A t1,A t2) {
if(t1.num==t2.num)
return t1.bz<t2.bz;
else return t1.num<t2.num;
}
int main() {
int T;
scanf("%d",&T);
while(T--) {
int n;
scanf("%d",&n);
for(int i=1;i<=n;++i) {
scanf("%d",&a[i].num);
a[i].bz=i;
}
sort(a+1,a+1+n,cmp);
/*for(int i=1;i<=n;++i) {
cout<<a[i].bz<<" "<<a[i].num<<endl;
}
continue;*/
int ans=inf;
for(int i=1;i<=n;++i) {
int h=i,t=i+1;
while(a[t].num==a[h].num) ++t;
--t;
int temp=0;
int sum=0;
for(int j=h;j<=t;++j) {
if(a[j].bz-temp>1) {
sum++;
}
temp=a[j].bz;
}
/* if(sum==0) {
cout<<h<<" "<<t<<endl;
for(int j=h;j<=t;++j) {
cout<<a[j].bz<<" "<<a[j].num<<endl;
}
}*/
if(n-a[t].bz>=1) ++sum;
ans=min(ans,sum);
i=t;
}
printf("%d\n",ans);
}
return 0;
}
D. Number into Sequence
唯一分解,找到幂次最大的数字,答案就是幂次数-1个该数,以及n/pow(该数,幂次数-1)。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<bitset>
#include<cassert>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<deque>
#include<iomanip>
#include<list>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
#include<unordered_set>
#include<unordered_map>
using namespace std;
//extern "C"{void *__dso_handle=0;}
typedef long long ll;
typedef long double ld;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define pii pair<int,int>
#define lowbit(x) x&-x
const double PI=acos(-1.0);
const double eps=1e-6;
const ll mod=1e9+7;
const int inf=0x3f3f3f3f;
const int maxn=2e5+10;
const int maxm=100+10;
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
ll qpow(ll a,ll b)
{
ll ans=1;
while(b)
{
if(b&1) ans*=a;
a*=a;
b>>=1;
}
return ans;
}
int main()
{
int t;
cin >> t;
while(t--)
{
ll n;
scanf("%lld",&n);
ll tmp=n,nt=sqrt(n);
ll maxx=-1,num=0;
for(int i=2;i<=nt;i++)
{
if(i>tmp) break;
if(tmp%i==0)
{
ll sum=0;
while(tmp%i==0)
{
sum++;
tmp/=i;
}
if(maxx<sum)
{
maxx=sum;
num=i;
}
}
}
if(tmp>1)
{
if(maxx<1)
{
maxx=1; num=tmp;
}
}
printf("%lld\n",maxx);
for(int i=1;i<maxx;i++) printf("%lld ",num);
printf("%lld\n",n/qpow(num,maxx-1));
}
}
E. Number of Simple Paths
由于n点n边,所以必有一环。那么整个图可以分为两种:环和非环(树)。
分情况讨论,环的简单路径个数为N*(N-1),非环(树)的简单路径个数为(N)*(N-1)/2,现在还有环与非环之间的简单路径以及非环与非环之间的简单路径。
环与非环之间的简单路径:xi*(N-1)*2(非环的点数)
非环与非环之间的简单路径:
∑
1
c
n
t
∑
j
=
i
+
1
c
n
t
(
x
[
i
]
−
1
)
∗
(
x
[
j
]
−
1
)
{\sum^{cnt}_{1}\sum^{cnt}_{j=i+1}(x[i]-1)*(x[j]-1)}
∑1cnt∑j=i+1cnt(x[i]−1)∗(x[j]−1)
cnt为非环的连通分支数。
关于非环点数:由环上的每个点向外扩展不包括环其它点的个数(包含环上的扩展点)。
所以样例3中非环点数为:1 2 2
所以本题需先dfs记录环的每个点。但是可能会出现一个包含1e5个点的环以及环的每个点连接一个点。总共2e5个点的图。这样在计算非环与非环之间的简单路径时可能会达到
O
(
(
1
e
5
)
2
)
{O((1e5)^2)}
O((1e5)2)的时间复杂度。
所以需要优化,
(
x
[
i
]
−
1
)
∗
(
x
[
j
]
−
1
)
=
x
[
i
]
∗
x
[
j
]
−
(
x
[
i
]
+
x
[
j
]
)
+
1
{(x[i]-1)*(x[j]-1)=x[i]*x[j]-(x[i]+x[j])+1}
(x[i]−1)∗(x[j]−1)=x[i]∗x[j]−(x[i]+x[j])+1
运用前缀和我们可以优化使之到达O(n)的时间复杂度来达到题目要求。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<bitset>
#include<cassert>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<deque>
#include<iomanip>
#include<list>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
using namespace std;
//extern "C"{void *__dso_handle=0;}
typedef long long ll;
typedef long double ld;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define pii pair<int,int>
#define lowbit(x) x&-x
const double PI=acos(-1.0);
const double eps=1e-6;
const ll mod=1e9+7;
const int inf=0x3f3f3f3f;
const int maxn=2e5+10;
const int maxm=100+10;
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
vector<int> g[maxn];
ll x[maxn],d[maxn];
vector<int> cir;
map<int,int> book;
int dfn[maxn],low[maxn];
int indx=0;
void dfs(int u,int f)
{
dfn[u]=low[u]=++indx;
for(int i=0;i<g[u].size();i++)
{
int v=g[u][i];
if(v==f) continue;
if(dfn[v]==-1)
{
dfs(v,u);
if(low[v]<low[u])
{
low[u]=low[v];
cir.push_back(u);
}
}
else if(dfn[v]<low[u])
{
cir.push_back(u);
cir.push_back(v);
low[u]=min(dfn[v],low[u]);
}
}
}
int dfs1(int u,int f)
{
int ans=1;
for(int i=0;i<g[u].size();i++)
{
int v=g[u][i];
if(v==f || book[v]) continue;
ans+=dfs1(v,u);
}
return ans;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
//memset(x,0,sizeof(x));
book.clear();
cir.clear();
ll n;
scanf("%lld",&n);
for(int i=0;i<=n;i++) dfn[i]=-1;
for(int i=1;i<=n;i++) g[i].clear();
for(int i=1;i<=n;i++)
{
int u,v; scanf("%d%d",&u,&v);
g[u].push_back(v);
g[v].push_back(u);
}
dfs(1,0);
ll T=cir.size();
for(int i=0;i<T;i++) book[cir[i]]=1;
int cnt=1;
for(int i=0;i<T;i++)
{
x[cnt++]=dfs1(cir[i],0);
}
ll ans=T*(T-1);
for(int i=1;i<cnt;i++)
{
ans+=x[i]*(x[i]-1)/2;
ans+=(x[i]-1)*2*(T-1);
}
vector<ll> p;
for(int i=1;i<cnt;i++)
{
if(x[i]>1) p.push_back(x[i]);
}
int len=p.size();
if(len>0) d[0]=p[0];
for(int i=1;i<len;i++) d[i]=d[i-1]+p[i];
for(int i=0;i<len-1;i++)
{
ans+=2*(len-1-i)+2*(-((len-i-1)*p[i]+d[len-1]-d[i])+p[i]*(d[len-1]-d[i]));
}
printf("%lld\n",ans);
}
}