题意:一个n边形,给定一个数字k,从顶点1开始每次隔k个点连一条线,每次输出这个n边形被分割成多少块区域。
思路:本次解题的关键是明确,每次新连一条线L,则增加的分割区域个数等于L穿过的线的条数+1。这样的话我们用树状数组维护,便于查询和更新信息。如果点u和点v之间连一条线,则a[u]++,a[u+k]++,然后线uv穿过的线的条数就是(u,v)之间点的个数。这是因为我们每连一条线,就在线段的两个端点+1,而如果uv之间的顶点存在这样的连线,那么一定会被uv所穿过。
代码one:
1 #include <iostream> 2 #include <queue> 3 #include <stack> 4 #include <cstdio> 5 #include <vector> 6 #include <map> 7 #include <set> 8 #include <bitset> 9 #include <algorithm> 10 #include <cmath> 11 #include <cstring> 12 #include <cstdlib> 13 #include <string> 14 #include <sstream> 15 #include <time.h> 16 #define x first 17 #define y second 18 #define pb push_back 19 #define mp make_pair 20 #define lson l,m,rt*2 21 #define rson m+1,r,rt*2+1 22 #define mt(A,B) memset(A,B,sizeof(A)) 23 #define mod 1000000007 24 using namespace std; 25 typedef long long LL; 26 const double PI = acos(-1); 27 const int N=1e6+10; 28 const int inf = 0x3f3f3f3f; 29 const LL INF=0x3f3f3f3f3f3f3f3fLL; 30 int n,k; 31 LL a[N],ans=1; 32 int lowbit(int x) 33 { 34 return x&(-x); 35 } 36 void update(int x) 37 { 38 while(x<=n) 39 { 40 a[x]++; 41 x+=lowbit(x); 42 } 43 } 44 LL sum(int x) 45 { 46 LL res=0; 47 while(x>0) 48 { 49 res+=a[x]; 50 x-=lowbit(x); 51 } 52 return res; 53 } 54 int main() 55 { 56 #ifdef Local 57 freopen("data","r",stdin); 58 #endif 59 int u=1; 60 cin>>n>>k; 61 k=min(k,n-k); 62 mt(a,0); 63 for(int i=0;i<n;i++) 64 { 65 update(u); 66 if((u+k)>n) 67 { 68 update((u+k)%n); 69 70 ans+=sum((u+k)%n-1)+sum(n)-sum(u)+1; 71 //cout<<1<<" "<<sum((u+k)%n-1)+sum(n)-sum(u)+1<<endl; 72 u=(u+k)%n; 73 } 74 else 75 { 76 update((u+k)); 77 ans+=sum(u+k-1)-sum(u)+1; 78 //cout<<2<<" "<<sum(u+k-1)-sum(u)+1<<endl; 79 u+=k; 80 } 81 if(i==n-1)cout<<ans<<endl; 82 else cout<<ans<<" "; 83 } 84 return 0; 85 #ifdef Local 86 cerr << "time: " << (LL) clock() * 1000 / CLOCKS_PER_SEC << " ms" << endl; 87 #endif 88 }
代码two:
PS:这个是昨晚打的时候想出来的,运气很不错的歪打正着,特此纪念。比树状数组快,实现也简单。纯找规律。
1 #include <iostream> 2 #include <queue> 3 #include <stack> 4 #include <cstdio> 5 #include <vector> 6 #include <map> 7 #include <set> 8 #include <bitset> 9 #include <algorithm> 10 #include <cmath> 11 #include <cstring> 12 #include <cstdlib> 13 #include <string> 14 #include <sstream> 15 #include <time.h> 16 #define x first 17 #define y second 18 #define pb push_back 19 #define mp make_pair 20 #define lson l,m,rt*2 21 #define rson m+1,r,rt*2+1 22 #define mt(A,B) memset(A,B,sizeof(A)) 23 #define mod 1000000007 24 using namespace std; 25 typedef long long LL; 26 const double PI = acos(-1); 27 const int N=1e6+10; 28 const int inf = 0x3f3f3f3f; 29 const LL INF=0x3f3f3f3f3f3f3f3fLL; 30 LL a[N]; 31 int main() 32 { 33 #ifdef Local 34 freopen("data","r",stdin); 35 #endif 36 LL n,k,cur=1,ans=1; 37 cin>>n>>k; 38 k=min(k,n-k); 39 for(LL i=1,j=1;i<=n;i++) 40 { 41 j+=k; 42 if(j>n) 43 { 44 cur++; 45 ans+=cur; 46 cur++; 47 j%=n; 48 } 49 else 50 { 51 ans+=cur; 52 } 53 if(i==n)cout<<ans-1<<endl; 54 else cout<<ans<<" "; 55 } 56 #ifdef Local 57 cerr << "time: " << (LL) clock() * 1000 / CLOCKS_PER_SEC << " ms" << endl; 58 #endif 59 }